fidl_fuchsia_sysmem2/fidl_fuchsia_sysmem2.rs
1// WARNING: This file is machine generated by fidlgen.
2
3#![warn(clippy::all)]
4#![allow(unused_parens, unused_mut, unused_imports, nonstandard_style)]
5
6use bitflags::bitflags;
7use fidl::client::QueryResponseFut;
8use fidl::encoding::{MessageBufFor, ProxyChannelBox, ResourceDialect};
9use fidl::endpoints::{ControlHandle as _, Responder as _};
10pub use fidl_fuchsia_sysmem2_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, Default, PartialEq)]
15pub struct AllocatorAllocateNonSharedCollectionRequest {
16 pub collection_request: Option<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
17 #[doc(hidden)]
18 pub __source_breaking: fidl::marker::SourceBreaking,
19}
20
21impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
22 for AllocatorAllocateNonSharedCollectionRequest
23{
24}
25
26#[derive(Debug, Default, PartialEq)]
27pub struct AllocatorAllocateSharedCollectionRequest {
28 pub token_request: Option<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
29 #[doc(hidden)]
30 pub __source_breaking: fidl::marker::SourceBreaking,
31}
32
33impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
34 for AllocatorAllocateSharedCollectionRequest
35{
36}
37
38#[derive(Debug, Default, PartialEq)]
39pub struct AllocatorBindSharedCollectionRequest {
40 pub token: Option<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
41 pub buffer_collection_request: Option<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
42 #[doc(hidden)]
43 pub __source_breaking: fidl::marker::SourceBreaking,
44}
45
46impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
47 for AllocatorBindSharedCollectionRequest
48{
49}
50
51#[derive(Debug, Default, PartialEq)]
52pub struct AllocatorGetVmoInfoRequest {
53 /// `vmo` is required to be set; ownership is transferred to the server
54 /// so in most cases a client will duplicate a handle and transfer the
55 /// duplicate via this field.
56 ///
57 /// The GetVmoInfo call will fail with `NOT_FOUND` if this VMO isn't a
58 /// sysmem-provided VMO. Children of sysmem-provided VMOs don't count as
59 /// sysmem-provided VMOs.
60 ///
61 /// Assuming this is a sysmem-provided VMO, the handle can be a sysmem
62 /// strong VMO handle or a sysmem weak VMO handle.
63 ///
64 /// If this field is sysmem weak VMO handle, `close_weak_asap` will be
65 /// set in the response (not the only reason for close_weak_asap to be
66 /// set).
67 ///
68 /// This field is required.
69 pub vmo: Option<fidl::Vmo>,
70 /// Iff set to true, a successful response will have weak_vmo set to a
71 /// sysmem weak VMO handle for the buffer, regardless of whether the vmo
72 /// handle in the request was weak or not.
73 ///
74 /// Also, when `weak_vmo` is set in the response, `close_weak_asap` will
75 /// also be set in the response, whether `vmo` was sysmem strong or
76 /// sysmem weak (not the only reason for close_weak_asap to be set).
77 ///
78 /// If set to true and `vmo` is a weak vmo and there aren't any
79 /// remaining strong vmo handles for the logical buffer (and the sysmem
80 /// server has had a chance to notice that), the request will fail with
81 /// `Error.NO_MORE_STRONG_VMO_HANDLES`.
82 ///
83 /// This field is optional. The default is false.
84 pub need_weak: Option<bool>,
85 /// Iff set to true, a successful response will have
86 /// single_buffer_settings set to the SingleBufferSettings for the
87 /// buffer's buffer collection.
88 ///
89 /// The fields in SingleBufferSettings can be thought of as similar in
90 /// nature to the information available from zx_object_get_info with
91 /// topic ZX_INFO_VMO, which doesn't require any rights on the VMO
92 /// handle to succeed. This information can be needed by the caller to
93 /// know how to correctly handle / use the VMO. Similarly, this call
94 /// doesn't require any particular rights in order to get
95 /// single_buffer_settings - just ZX_RIGHT_TRANSFER for the client's
96 /// message to send successfully, and of course the `vmo` field must be
97 /// a handle to a sysmem-provided VMO.
98 ///
99 /// Clients should avoid manually checking whether
100 /// `single_buffer_settings` is consistent with the client's
101 /// BufferCollectionConstraints (or at least, shouldn't only rely on
102 /// that checking in the client). To have sysmem check, see
103 /// `constraints_to_check`.
104 ///
105 /// This field is optional. The default is false.
106 pub need_single_buffer_settings: Option<bool>,
107 /// Iff set, `constraints_ok` will be set in the response indicating
108 /// whether the sent constraints are compatible with the parent buffer
109 /// collection as allocated.
110 ///
111 /// Buffer counts are not checked for consistency, as there's no way for
112 /// sysmem to know whether the passed-in `vmo` was originally handed out
113 /// to the same logical participant that's now checking the vmo against
114 /// its constraints, and we also want to avoid adding things that might
115 /// lock sysmem into a static number of buffers per collection.
116 ///
117 /// This can be thought of as checking `constraints_to_check` against
118 /// the `single_buffer_settings` (if that is/were requested), but sysmem
119 /// is free to check against additional info as well (such as a
120 /// hypothetical future sysmem3's buffer collection info, or modified
121 /// semantics for sysmem2 fields that this client hasn't opted into, or
122 /// similar). In other words, clients should let sysmem do this check,
123 /// regardless of whether the client also does some checking of its own.
124 ///
125 /// This field is optional. If un-set, no constraints checking occurs.
126 pub constraints_to_check: Option<BufferCollectionConstraints>,
127 /// If set, `vmo_settings_match` will be set to indicate whether the
128 /// parent collection of `vmo` and `vmo_settings_to_check` have the same
129 /// SingleBufferSettings. This will be true if both are the same VMO,
130 /// will be true if both VMOs are from the same collection, and can also
131 /// be true if two VMOs from different collections have the same
132 /// SingleBufferSettings.
133 pub vmo_settings_to_check: Option<fidl::Vmo>,
134 /// When vmo_settings_to_check is set to a VMO and
135 /// vmo_settings_to_check_ignore_size is set to true, the buffer size
136 /// is ignored when comparing the two buffer's settings. This can be
137 /// useful to set when checking video decoder input buffers.
138 pub vmo_settings_to_check_ignore_size: Option<bool>,
139 #[doc(hidden)]
140 pub __source_breaking: fidl::marker::SourceBreaking,
141}
142
143impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
144 for AllocatorGetVmoInfoRequest
145{
146}
147
148#[derive(Debug, Default, PartialEq)]
149pub struct AllocatorGetVmoInfoResponse {
150 /// The buffer_collection_id and buffer_index together uniquely identify
151 /// a buffer per boot.
152 pub buffer_collection_id: Option<u64>,
153 /// The buffer_collection_id and buffer_index together uniquely identify
154 /// a buffer per boot.
155 ///
156 /// This buffer_index is in the same space as specified/implied by
157 /// `BufferCollectionInfo` from collection allocation.
158 ///
159 /// Clients that don't have direct control over the provenance of `vmo`
160 /// should assume that buffer_index could be any uint64. Such clients
161 /// may wish to check the buffer_collection_id against client-known
162 /// buffer collections before looking at buffer_index, and/or ensure
163 /// that looking up a client-known buffer by buffer_collection_id and
164 /// buffer_index doesn't rely on buffer_index(s) being packed near 0, at
165 /// least until a client-known buffer is found that the client knows
166 /// will have buffer_index packed near 0.
167 pub buffer_index: Option<u64>,
168 /// If vmo was a sysmem weak VMO handle or need_weak was set to true (or
169 /// both), this field will be set. Later when ZX_EVENTPAIR_PEER_CLOSED
170 /// is signalled on this eventpair endpoint, all weak VMO handles to
171 /// this buffer should be closed asap (all strong VMO handles were
172 /// already closed by this point). In some cases, a client may be able
173 /// to rely on a different participant to notice and inform the client,
174 /// so this field being set is potentially ignore-able by some clients.
175 ///
176 /// Client authors should ensure that when the buffer's close_weak_asap
177 /// server_end closes, the client will close all handles to the buffer
178 /// as soon as possible. This can be achieved directly or indirectly.
179 /// Client authors should not assume that this is achieved indirectly.
180 pub close_weak_asap: Option<fidl::EventPair>,
181 /// Iff `need_weak` was set to true, this field is set to a sysmem weak
182 /// VMO handle to the same sysmem buffer (assuming no Error). The koid
183 /// may be different than the koid of the `vmo` in the request,
184 /// regardless of whether `vmo` in the request was a strong or weak VMO
185 /// handle. The `weak_vmo` will have no more rights than the `vmo`
186 /// handle had. In most cases, the client should also retain
187 /// `close_weak_asap` and notice when ZX_EVENTPAIR_PEER_CLOSED is
188 /// signalled and close the `weak_vmo` (and any handles to child VMOs)
189 /// ASAP.
190 pub weak_vmo: Option<fidl::Vmo>,
191 /// Iff `need_single_buffer_settings` is set, this field will be set to
192 /// the SingleBufferSettings of the vmo's collection. See also
193 /// `[fuchsia.sysmem2/Allocator.GetVmoInfo]`
194 /// `need_single_buffer_settings`.
195 pub single_buffer_settings: Option<SingleBufferSettings>,
196 /// Iff `constraints_to_check` was set, this field will be set. If true,
197 /// the vmo conforms to `constraints_to_check`. If false, the vmo does
198 /// not conform to `constraints_to_check`.
199 pub constraints_ok: Option<bool>,
200 /// Iff `vmo_settings_to_check` was set, this field will be set. If
201 /// true, `vmo` and `vmo_settings_to_check` have the same
202 /// SingleBufferSettings. If false, `vmo` and `vmo_settings_to_check`
203 /// have different SingleBufferSettings. The reason for not matching may
204 /// not be visible to the client if SingleBufferSettings has a new field
205 /// or similar.
206 pub vmo_settings_match: Option<bool>,
207 #[doc(hidden)]
208 pub __source_breaking: fidl::marker::SourceBreaking,
209}
210
211impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
212 for AllocatorGetVmoInfoResponse
213{
214}
215
216#[derive(Debug, Default, PartialEq)]
217pub struct BufferCollectionAttachLifetimeTrackingRequest {
218 pub server_end: Option<fidl::EventPair>,
219 pub buffers_remaining: Option<u32>,
220 #[doc(hidden)]
221 pub __source_breaking: fidl::marker::SourceBreaking,
222}
223
224impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
225 for BufferCollectionAttachLifetimeTrackingRequest
226{
227}
228
229#[derive(Debug, Default, PartialEq)]
230pub struct BufferCollectionAttachTokenRequest {
231 pub rights_attenuation_mask: Option<fidl::Rights>,
232 pub token_request: Option<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
233 #[doc(hidden)]
234 pub __source_breaking: fidl::marker::SourceBreaking,
235}
236
237impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
238 for BufferCollectionAttachTokenRequest
239{
240}
241
242/// Information about a buffer collection and its buffers.
243///
244/// When adding fields to this table, see also
245/// fuchsia.sysmem2/Allocator.GetVmoInfo, redacted_buffer_collection_info, and
246/// RedactBufferCollectionInfo. Consider whether a client with only
247/// ZX_RIGHT_TRANSFER right on a sysmem vmo handle, calling GetVmoInfo, should
248/// be given the information in the new field, or whether it should be un-set
249/// during redaction. GetVmoInfo is analogous to zx_object_get_info with topic
250/// ZX_INFO_VMO, which doesn't require the VMO handle to have any rights - just
251/// needs to be a handle to a VMO. Fields that are necessary to correctly use a
252/// single sysmem VMO in isolation are generally ok (but still think about it
253/// field by field). Fields that are not necessary to correctly use a single
254/// sysmem VMO in isolation should probably be redacted for GetVmoInfo
255/// redacted_buffer_collection_info.
256#[derive(Debug, Default, PartialEq)]
257pub struct BufferCollectionInfo {
258 /// These settings apply to all the buffers in the initial buffer
259 /// allocation.
260 ///
261 /// This field will always be set by sysmem.
262 pub settings: Option<SingleBufferSettings>,
263 /// VMO handles (and vmo_usable_start offset) for each buffer in the
264 /// collection.
265 ///
266 /// The size of this vector is the buffer_count (buffer_count is not sent
267 /// separately).
268 ///
269 /// All buffer VMO handles have identical size and access rights. The size
270 /// is in settings.buffer_settings.size_bytes.
271 ///
272 /// The VMO access rights are determined based on the usages which the
273 /// client specified when allocating the buffer collection. For example, a
274 /// client which expressed a read-only usage will receive VMOs without write
275 /// rights. In addition, the rights can be attenuated by the parameter to
276 /// BufferCollectionToken.Duplicate() calls.
277 ///
278 /// This field will always have VmoBuffer(s) in it, even if the participant
279 /// specifies usage whieh does not require VMO handles. This permits such a
280 /// participant to know the vmo_usable_start values, in case that's of any
281 /// use to the participant.
282 ///
283 /// This field will always be set by sysmem, even if the participant doesn't
284 /// specify any buffer usage (but the [`fuchsia.sysmem2/VmoBuffer.vmo`]
285 /// sub-field within this field won't be set in that case).
286 ///
287 /// In the response from `[fuchsia.sysmem2/Allocator.GetVmoInfo]`, in the
288 /// redacted_buffer_collection_info, this field is un-set.
289 pub buffers: Option<Vec<VmoBuffer>>,
290 /// This number is unique among all logical buffer collections per boot.
291 ///
292 /// This ID number will be the same for all BufferCollectionToken(s),
293 /// BufferCollection(s), and BufferCollectionTokenGroup(s) associated with
294 /// the same logical buffer collection (derived from the same root token
295 /// created with fuchsia.sysmem2.Allocator.CreateSharedCollection, or with
296 /// CreateNonSharedCollection).
297 ///
298 /// The same ID can be retrieved from a BufferCollectionToken,
299 /// BufferCollection, or BufferCollectionTokenGroup using
300 /// GetBufferCollectionId (at the cost of a round-trip to sysmem and back).
301 ///
302 /// This field will always be set by sysmem.
303 pub buffer_collection_id: Option<u64>,
304 #[doc(hidden)]
305 pub __source_breaking: fidl::marker::SourceBreaking,
306}
307
308impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for BufferCollectionInfo {}
309
310#[derive(Debug, Default, PartialEq)]
311pub struct BufferCollectionSetConstraintsRequest {
312 /// These are the constraints on the buffer collection imposed by the
313 /// sending client/participant. The `constraints` field is not required
314 /// to be set. If not set, the client is not setting any actual
315 /// constraints, but is indicating that the client has no constraints to
316 /// set. A client that doesn't set the `constraints` field won't receive
317 /// any VMO handles, but can still find out how many buffers were
318 /// allocated and can still refer to buffers by their `buffer_index`.
319 pub constraints: Option<BufferCollectionConstraints>,
320 /// This field should only be set if a client must force the new buffer
321 /// collection to have exactly identical SingleBufferSettings as a
322 /// previously-allocated collection, else the allocation must fail.
323 ///
324 /// Setting this field nails down all the constraints except the buffer
325 /// count, so clients shouldn't expect this to work unless the overall
326 /// set of participants on this logical buffer collection is the same as
327 /// for the previous allocation (though this isn't strictly required to
328 /// be true). Even then, if any participant indicates different
329 /// constraints than for this VMO's collection, the allocation is fairly
330 /// likely to fail. For these reasons, clients will want to avoid
331 /// setting this field unless it's really needed.
332 ///
333 /// The `must_match_vmo` handle must be a handle to a sysmem-provided
334 /// VMO, else the logical buffer collection will fail. To check whether
335 /// a VMO handle refers to a sysmem-provided VMO before setting this
336 /// field (if not already known), see
337 /// `[fuchsia.sysmem2/Allocator.GetVmoInfo]`.
338 ///
339 /// This still ensures that constraints of other participants are
340 /// satisfied as well, else the allocation will fail.
341 ///
342 /// This field is a VMO rather than SingleBufferSettings so that adding
343 /// a new field to SingleBufferSettings remains compatible with this
344 /// mechanism without needing to update/rebuild all clients using this
345 /// mechanism to copy the new field.
346 ///
347 /// This field is a VMO rather than a "handle to a SingleBufferSettings"
348 /// (or similar) to avoid this field causing allocation failure when
349 /// there are zero actual still-existing buffers to match (in which case
350 /// not setting this field is better than letting an already-gone buffer
351 /// dictate the settings for new buffers).
352 ///
353 /// Clients should avoid keeping a buffer alive just to use it with this
354 /// field; instead drop the old buffer when appropriate, and allocate
355 /// new buffer(s) like it's the first allocation after boot again.
356 ///
357 /// See also `[fuchsia.sysmem2/BufferCollection.AttachToken]` which is a
358 /// substantially different mechanism, but might be a workable
359 /// alternative to setting this feild in a few (but not all) situations
360 /// that would otherwise need to set this field.
361 ///
362 /// In most cases the constraints field should specify all the necessary
363 /// constraints known to the client, and this field should not be set.
364 pub must_match_vmo: Option<fidl::Vmo>,
365 #[doc(hidden)]
366 pub __source_breaking: fidl::marker::SourceBreaking,
367}
368
369impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
370 for BufferCollectionSetConstraintsRequest
371{
372}
373
374#[derive(Debug, Default, PartialEq)]
375pub struct BufferCollectionTokenCreateBufferCollectionTokenGroupRequest {
376 pub group_request: Option<fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>>,
377 #[doc(hidden)]
378 pub __source_breaking: fidl::marker::SourceBreaking,
379}
380
381impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
382 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
383{
384}
385
386#[derive(Debug, Default, PartialEq)]
387pub struct BufferCollectionTokenDuplicateRequest {
388 pub rights_attenuation_mask: Option<fidl::Rights>,
389 pub token_request: Option<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
390 #[doc(hidden)]
391 pub __source_breaking: fidl::marker::SourceBreaking,
392}
393
394impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
395 for BufferCollectionTokenDuplicateRequest
396{
397}
398
399#[derive(Debug, Default, PartialEq)]
400pub struct BufferCollectionTokenGroupCreateChildRequest {
401 /// Must be set.
402 pub token_request: Option<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
403 /// If not set, the default is `ZX_RIGHT_SAME_RIGHTS`.
404 pub rights_attenuation_mask: Option<fidl::Rights>,
405 #[doc(hidden)]
406 pub __source_breaking: fidl::marker::SourceBreaking,
407}
408
409impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
410 for BufferCollectionTokenGroupCreateChildRequest
411{
412}
413
414#[derive(Debug, Default, PartialEq)]
415pub struct BufferCollectionTokenGroupCreateChildrenSyncResponse {
416 pub tokens: Option<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>>,
417 #[doc(hidden)]
418 pub __source_breaking: fidl::marker::SourceBreaking,
419}
420
421impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
422 for BufferCollectionTokenGroupCreateChildrenSyncResponse
423{
424}
425
426#[derive(Debug, Default, PartialEq)]
427pub struct BufferCollectionTokenDuplicateSyncResponse {
428 pub tokens: Option<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>>,
429 #[doc(hidden)]
430 pub __source_breaking: fidl::marker::SourceBreaking,
431}
432
433impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
434 for BufferCollectionTokenDuplicateSyncResponse
435{
436}
437
438#[derive(Debug, Default, PartialEq)]
439pub struct BufferCollectionWaitForAllBuffersAllocatedResponse {
440 pub buffer_collection_info: Option<BufferCollectionInfo>,
441 #[doc(hidden)]
442 pub __source_breaking: fidl::marker::SourceBreaking,
443}
444
445impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
446 for BufferCollectionWaitForAllBuffersAllocatedResponse
447{
448}
449
450#[derive(Debug, Default, PartialEq)]
451pub struct NodeAttachNodeTrackingRequest {
452 /// This field must be set. This evenpair end will be closed after the
453 /// `Node` is closed or failed and the node's buffer counts are no
454 /// longer in effect in the logical buffer collection.
455 pub server_end: Option<fidl::EventPair>,
456 #[doc(hidden)]
457 pub __source_breaking: fidl::marker::SourceBreaking,
458}
459
460impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
461 for NodeAttachNodeTrackingRequest
462{
463}
464
465#[derive(Debug, Default, PartialEq)]
466pub struct NodeIsAlternateForRequest {
467 pub node_ref: Option<fidl::Event>,
468 #[doc(hidden)]
469 pub __source_breaking: fidl::marker::SourceBreaking,
470}
471
472impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for NodeIsAlternateForRequest {}
473
474#[derive(Debug, Default, PartialEq)]
475pub struct NodeSetWeakOkRequest {
476 pub for_child_nodes_also: Option<bool>,
477 #[doc(hidden)]
478 pub __source_breaking: fidl::marker::SourceBreaking,
479}
480
481impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for NodeSetWeakOkRequest {}
482
483#[derive(Debug, Default, PartialEq)]
484pub struct NodeGetNodeRefResponse {
485 pub node_ref: Option<fidl::Event>,
486 #[doc(hidden)]
487 pub __source_breaking: fidl::marker::SourceBreaking,
488}
489
490impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for NodeGetNodeRefResponse {}
491
492#[derive(Debug, Default, PartialEq)]
493pub struct VmoBuffer {
494 /// `vmo` can be un-set if a participant has only
495 /// [`fuchsia.sysmem2/BufferUsage.none`] set to `NONE_USAGE` (explicitly or
496 /// implicitly by [`fuchsia.sysmem2/BufferCollection.SetConstraints`]
497 /// without `constraints` set).
498 pub vmo: Option<fidl::Vmo>,
499 /// Offset within the VMO of the first usable byte. Must be < the VMO's size
500 /// in bytes, and leave sufficient room for BufferMemorySettings.size_bytes
501 /// before the end of the VMO.
502 ///
503 /// Currently sysmem will always set this field to 0, and in future, sysmem
504 /// won't set this field to a non-zero value unless all participants have
505 /// explicitly indicated support for non-zero vmo_usable_start (this
506 /// mechanism does not exist as of this comment). A participant that hasn't
507 /// explicitly indicated support for non-zero vmo_usable_start (all current
508 /// clients) should implicitly assume this field is set to 0 without
509 /// actually checking this field.
510 pub vmo_usable_start: Option<u64>,
511 /// This field is set iff `vmo` is a sysmem weak VMO handle.
512 ///
513 /// If the client sent `SetWeakOk`, the client must keep `close_weak_asap`
514 /// around for as long as `vmo`, and must notice `ZX_EVENTPAIR_PEER_CLOSED`.
515 /// If that signal occurs, the client must close `vmo` asap.
516 ///
517 /// If the `vmo` is a sysmem weak VMO handle but the client didn't send
518 /// `SetWeakOk`, this means that a holder of a parent node sent `SetWeakOk`
519 /// with `for_child_nodes_also` true, and the owner of that parent node is
520 /// responsible for paying attention to `close_weak_asap` and informing
521 /// child token participants to close handles. In this case the participant
522 /// that never sent `SetWeakOk` is allowed to retain and/or pay attention to
523 /// `close_weak_asap` (to close the handle faster, or for other reasons such
524 /// as diagnosing overall buffer cleanup timing), but is not required to
525 /// retain or pay attention to `close_weak_asap`.
526 ///
527 /// If sysmem closing the sysmem end of `close_weak_asap` does not result in
528 /// quick closure of all sysmem weak VMO handles to the buffer, that's
529 /// considered a VMO leak, and in that case sysmem will eventually complain
530 /// loudly via syslog (currently 5s later).
531 pub close_weak_asap: Option<fidl::EventPair>,
532 #[doc(hidden)]
533 pub __source_breaking: fidl::marker::SourceBreaking,
534}
535
536impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for VmoBuffer {}
537
538#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
539pub struct AllocatorMarker;
540
541impl fidl::endpoints::ProtocolMarker for AllocatorMarker {
542 type Proxy = AllocatorProxy;
543 type RequestStream = AllocatorRequestStream;
544 #[cfg(target_os = "fuchsia")]
545 type SynchronousProxy = AllocatorSynchronousProxy;
546
547 const DEBUG_NAME: &'static str = "fuchsia.sysmem2.Allocator";
548}
549impl fidl::endpoints::DiscoverableProtocolMarker for AllocatorMarker {}
550pub type AllocatorGetVmoInfoResult = Result<AllocatorGetVmoInfoResponse, Error>;
551
552pub trait AllocatorProxyInterface: Send + Sync {
553 fn r#allocate_non_shared_collection(
554 &self,
555 payload: AllocatorAllocateNonSharedCollectionRequest,
556 ) -> Result<(), fidl::Error>;
557 fn r#allocate_shared_collection(
558 &self,
559 payload: AllocatorAllocateSharedCollectionRequest,
560 ) -> Result<(), fidl::Error>;
561 fn r#bind_shared_collection(
562 &self,
563 payload: AllocatorBindSharedCollectionRequest,
564 ) -> Result<(), fidl::Error>;
565 type ValidateBufferCollectionTokenResponseFut: std::future::Future<
566 Output = Result<AllocatorValidateBufferCollectionTokenResponse, fidl::Error>,
567 > + Send;
568 fn r#validate_buffer_collection_token(
569 &self,
570 payload: &AllocatorValidateBufferCollectionTokenRequest,
571 ) -> Self::ValidateBufferCollectionTokenResponseFut;
572 fn r#set_debug_client_info(
573 &self,
574 payload: &AllocatorSetDebugClientInfoRequest,
575 ) -> Result<(), fidl::Error>;
576 type GetVmoInfoResponseFut: std::future::Future<Output = Result<AllocatorGetVmoInfoResult, fidl::Error>>
577 + Send;
578 fn r#get_vmo_info(&self, payload: AllocatorGetVmoInfoRequest) -> Self::GetVmoInfoResponseFut;
579}
580#[derive(Debug)]
581#[cfg(target_os = "fuchsia")]
582pub struct AllocatorSynchronousProxy {
583 client: fidl::client::sync::Client,
584}
585
586#[cfg(target_os = "fuchsia")]
587impl fidl::endpoints::SynchronousProxy for AllocatorSynchronousProxy {
588 type Proxy = AllocatorProxy;
589 type Protocol = AllocatorMarker;
590
591 fn from_channel(inner: fidl::Channel) -> Self {
592 Self::new(inner)
593 }
594
595 fn into_channel(self) -> fidl::Channel {
596 self.client.into_channel()
597 }
598
599 fn as_channel(&self) -> &fidl::Channel {
600 self.client.as_channel()
601 }
602}
603
604#[cfg(target_os = "fuchsia")]
605impl AllocatorSynchronousProxy {
606 pub fn new(channel: fidl::Channel) -> Self {
607 Self { client: fidl::client::sync::Client::new(channel) }
608 }
609
610 pub fn into_channel(self) -> fidl::Channel {
611 self.client.into_channel()
612 }
613
614 /// Waits until an event arrives and returns it. It is safe for other
615 /// threads to make concurrent requests while waiting for an event.
616 pub fn wait_for_event(
617 &self,
618 deadline: zx::MonotonicInstant,
619 ) -> Result<AllocatorEvent, fidl::Error> {
620 AllocatorEvent::decode(self.client.wait_for_event::<AllocatorMarker>(deadline)?)
621 }
622
623 /// Allocates a buffer collection on behalf of a single client (aka
624 /// initiator) who is also the only participant (from the point of view of
625 /// sysmem).
626 ///
627 /// This call exists mainly for temp/testing purposes. This call skips the
628 /// [`fuchsia.sysmem2/BufferCollectionToken`] stage, so there's no way to
629 /// allow another participant to specify its constraints.
630 ///
631 /// Real clients are encouraged to use
632 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`] instead, and to
633 /// let relevant participants directly convey their own constraints to
634 /// sysmem by sending `BufferCollectionToken`s to those participants.
635 ///
636 /// + request `collection_request` The server end of the
637 /// [`fuchsia.sysmem2/BufferCollection`].
638 pub fn r#allocate_non_shared_collection(
639 &self,
640 mut payload: AllocatorAllocateNonSharedCollectionRequest,
641 ) -> Result<(), fidl::Error> {
642 self.client.send::<AllocatorAllocateNonSharedCollectionRequest>(
643 &mut payload,
644 0x5ca681f025a80e44,
645 fidl::encoding::DynamicFlags::FLEXIBLE,
646 )
647 }
648
649 /// Creates a root [`fuchsia.sysmem2/BufferCollectionToken`].
650 ///
651 /// The `BufferCollectionToken` can be "duplicated" for distribution to
652 /// participants by using
653 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`]. Each
654 /// `BufferCollectionToken` can be converted into a
655 /// [`fuchsia.sysmem2.BufferCollection`] using
656 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`].
657 ///
658 /// Buffer constraints can be set via
659 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
660 ///
661 /// Success/failure to populate the buffer collection with buffers can be
662 /// determined from
663 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
664 ///
665 /// Closing the client end of a `BufferCollectionToken` or
666 /// `BufferCollection` (without `Release` first) will fail all client ends
667 /// in the same failure domain, which by default is all client ends of the
668 /// buffer collection. See
669 /// [`fuchsia.sysmem2/BufferCollection.SetDispensable`] and
670 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`] for ways to create
671 /// separate failure domains within a buffer collection.
672 pub fn r#allocate_shared_collection(
673 &self,
674 mut payload: AllocatorAllocateSharedCollectionRequest,
675 ) -> Result<(), fidl::Error> {
676 self.client.send::<AllocatorAllocateSharedCollectionRequest>(
677 &mut payload,
678 0x11a19ff51f0b49c1,
679 fidl::encoding::DynamicFlags::FLEXIBLE,
680 )
681 }
682
683 /// Convert a [`fuchsia.sysmem2/BufferCollectionToken`] into a
684 /// [`fuchsia.sysmem2/BufferCollection`].
685 ///
686 /// At the time of sending this message, the buffer collection hasn't yet
687 /// been populated with buffers - the participant must first also send
688 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] via the
689 /// `BufferCollection` client end.
690 ///
691 /// All `BufferCollectionToken`(s) duplicated from a root
692 /// `BufferCollectionToken` (created via `AllocateSharedCollection`) must be
693 /// "turned in" via `BindSharedCollection` (or `Release`ed), and all
694 /// existing `BufferCollection` client ends must have sent `SetConstraints`
695 /// before the logical BufferCollection will be populated with buffers (or
696 /// will fail if the overall set of constraints can't be satisfied).
697 ///
698 /// + request `token` The client endpoint of a channel whose server end was
699 /// sent to sysmem using
700 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`] or whose server
701 /// end was sent to sysmem using
702 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`]. The token is
703 /// being "turned in" in exchange for a
704 /// [`fuchsia.sysmem2/BufferCollection`].
705 /// + request `buffer_collection_request` The server end of a
706 /// [`fuchsia.sysmem2/BufferCollection`] channel. The sender retains the
707 /// client end. The `BufferCollection` channel is a single participant's
708 /// connection to the logical buffer collection. Typically there will be
709 /// other participants with their own `BufferCollection` channel to the
710 /// logical buffer collection.
711 pub fn r#bind_shared_collection(
712 &self,
713 mut payload: AllocatorBindSharedCollectionRequest,
714 ) -> Result<(), fidl::Error> {
715 self.client.send::<AllocatorBindSharedCollectionRequest>(
716 &mut payload,
717 0x550916b0dc1d5b4e,
718 fidl::encoding::DynamicFlags::FLEXIBLE,
719 )
720 }
721
722 /// Checks whether a [`fuchsia.sysmem2/BufferCollectionToken`] is known to
723 /// the sysmem server.
724 ///
725 /// With this call, the client can determine whether an incoming token is a
726 /// real sysmem token that is known to the sysmem server, without any risk
727 /// of getting stuck waiting forever on a potentially fake token to complete
728 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] or
729 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] (or any other two-way
730 /// FIDL message). In cases where the client trusts the source of the token
731 /// to provide a real token, this call is not typically needed outside of
732 /// debugging.
733 ///
734 /// If the validate fails sometimes but succeeds other times, the source of
735 /// the token may itself not be calling
736 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] or
737 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after creating/duplicating the
738 /// token but before sending the token to the current client. It may be more
739 /// convenient for the source to use
740 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] to duplicate
741 /// token(s), since that call has the sync step built in. Or, the buffer
742 /// collection may be failing before this call is processed by the sysmem
743 /// server, as buffer collection failure cleans up sysmem's tracking of
744 /// associated tokens.
745 ///
746 /// This call has no effect on any token.
747 ///
748 /// + request `token_server_koid` The koid of the server end of a channel
749 /// that might be a BufferCollectionToken channel. This can be obtained
750 /// via `zx_object_get_info` `ZX_INFO_HANDLE_BASIC` `related_koid`.
751 /// - response `is_known` true means sysmem knew of the token at the time
752 /// sysmem processed the request, but doesn't guarantee that the token is
753 /// still valid by the time the client receives the reply. What it does
754 /// guarantee is that the token at least was a real token, so a two-way
755 /// call to the token won't stall forever (will fail or succeed fairly
756 /// quickly, not stall). This can already be known implicitly if the
757 /// source of the token can be trusted to provide a real token. A false
758 /// value means the token wasn't known to sysmem at the time sysmem
759 /// processed this call, but the token may have previously been valid, or
760 /// may yet become valid. Or if the sender of the token isn't trusted to
761 /// provide a real token, the token may be fake. It's the responsibility
762 /// of the sender to sync with sysmem to ensure that previously
763 /// created/duplicated token(s) are known to sysmem, before sending the
764 /// token(s) to other participants.
765 pub fn r#validate_buffer_collection_token(
766 &self,
767 mut payload: &AllocatorValidateBufferCollectionTokenRequest,
768 ___deadline: zx::MonotonicInstant,
769 ) -> Result<AllocatorValidateBufferCollectionTokenResponse, fidl::Error> {
770 let _response = self.client.send_query::<
771 AllocatorValidateBufferCollectionTokenRequest,
772 fidl::encoding::FlexibleType<AllocatorValidateBufferCollectionTokenResponse>,
773 AllocatorMarker,
774 >(
775 payload,
776 0x4c5ee91b02a7e68d,
777 fidl::encoding::DynamicFlags::FLEXIBLE,
778 ___deadline,
779 )?
780 .into_result::<AllocatorMarker>("validate_buffer_collection_token")?;
781 Ok(_response)
782 }
783
784 /// Set information about the current client that can be used by sysmem to
785 /// help diagnose leaking memory and allocation stalls waiting for a
786 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
787 ///
788 /// This sets the debug client info on all [`fuchsia.sysmem2/Node`](s)
789 /// subsequently created by this this [`fuchsia.sysmem2/Allocator`]
790 /// including any [`fuchsia.sysmem2/BufferCollection`](s) created via
791 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] (in the absence of
792 /// any prior call to [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`],
793 /// these `BufferCollection`(s) have the same initial debug client info as
794 /// the token turned in to create the `BufferCollection`).
795 ///
796 /// This info can be subsequently overridden on a per-`Node` basis by
797 /// sending [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
798 ///
799 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
800 /// `Allocator` is the most efficient way to ensure that all
801 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
802 /// set, and is also more efficient than separately sending the same debug
803 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
804 /// created [`fuchsia.sysmem2/Node`].
805 ///
806 /// + request `name` This can be an arbitrary string, but the current
807 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
808 /// + request `id` This can be an arbitrary id, but the current process ID
809 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
810 pub fn r#set_debug_client_info(
811 &self,
812 mut payload: &AllocatorSetDebugClientInfoRequest,
813 ) -> Result<(), fidl::Error> {
814 self.client.send::<AllocatorSetDebugClientInfoRequest>(
815 payload,
816 0x6f68f19a3f509c4d,
817 fidl::encoding::DynamicFlags::FLEXIBLE,
818 )
819 }
820
821 /// Given a handle to a sysmem-provided VMO, this returns additional info
822 /// about the corresponding sysmem logical buffer.
823 ///
824 /// Most callers will duplicate a VMO handle first and send the duplicate to
825 /// this call.
826 ///
827 /// If the client has created a child VMO of a sysmem-provided VMO, that
828 /// child VMO isn't considered a "sysmem VMO" for purposes of this call.
829 ///
830 /// + request `vmo` A handle to a sysmem-provided VMO (or see errors).
831 /// + request `need_weak` Iff set to true, the response will have weak_vmo
832 /// set to a weak VMO for the buffer, regardless of whether `vmo` in the
833 /// request was weak or strong.
834 /// - response `buffer_collection_id` The buffer collection ID, which is
835 /// unique per logical buffer collection per boot.
836 /// - response `buffer_index` The buffer index of the buffer within the
837 /// buffer collection. This is the same as the index of the buffer within
838 /// [`fuchsia.sysmem2/BufferCollectionInfo.buffers`]. The `buffer_index`
839 /// is the same for all sysmem-delivered VMOs corresponding to the same
840 /// logical buffer, even if the VMO koids differ. The `buffer_index` is
841 /// only unique across buffers of a buffer collection. For a given buffer,
842 /// the combination of `buffer_collection_id` and `buffer_index` is unique
843 /// per boot.
844 /// - response `close_weak_asap` Iff `vmo` is a handle to a weak sysmem VMO
845 /// OR need_weak is set to true, the `close_weak_asap` field will be set
846 /// in the response. This handle will signal `ZX_EVENTPAIR_PEER_CLOSED`
847 /// when all weak VMO handles to the buffer should be closed as soon as
848 /// possible. This is signalled shortly after all strong sysmem VMOs to
849 /// the buffer are closed (including any held indirectly via strong
850 /// `BufferCollectionToken` or strong `BufferCollection`). Failure to
851 /// close all weak sysmem VMO handles to the buffer quickly upon
852 /// `ZX_EVENTPAIR_PEER_CLOSED` is considered a VMO leak caused by the
853 /// client still holding a weak sysmem VMO handle and results in loud
854 /// complaints to the log by sysmem (after a delay). The buffers of a
855 /// collection can be freed independently of each other. The
856 /// `ZX_EVENTPAIR_PEER_CLOSED` may already be signalled before the
857 /// response arrives at the client. A client that isn't prepared to
858 /// directly handle weak sysmem VMOs and waiting on close_weak_asap, on
859 /// seeing this field set in response to a request that had need_weak
860 /// un-set, typically should ignore the fact that the vmo handle was a
861 /// weak vmo handle; typically another participant that's also a client of
862 /// this participant via some other protocol has taken responsibility for
863 /// ensuring that this participant will close all handles to the buffer,
864 /// typically by shutting down this participant's context holding a vmo
865 /// handle in some other way. That said, it is not harmful for both
866 /// participants to directly handle close_weak_asap, even if one
867 /// participant can take responsibility for handling close_weak_asap. See
868 /// also `[fuchsia.sysmem2/Node.SetWeakOk]` for_child_nodes_also.
869 /// - response `weak_vmo` This field is set in the response iff the request
870 /// had `need_weak` set to true. When set, this is a weak VMO handle to
871 /// the same buffer as `vmo` in the request, but may not have the same
872 /// koid as `vmo` had (this applies regardless of whether `vmo` was strong
873 /// or weak).
874 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` - the vmo isn't a sysmem
875 /// VMO. Both strong and weak sysmem VMOs can be passed to this call, and
876 /// the VMO handle passed in to this call itself keeps the VMO's info
877 /// alive for purposes of responding to this call. Because of this,
878 /// ZX_ERR_NOT_FOUND errors are unambiguous (even if there are no other
879 /// handles to the VMO when calling; even if other handles are closed
880 /// before the GetVmoInfo response arrives at the client).
881 /// * error `[fuchsia.sysmem2/Error.UNSPECIFIED]` The request failed for an
882 /// unspecified reason. See the log for more info.
883 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The vmo field
884 /// wasn't set, or there was some other problem with the request field(s).
885 /// See the log.
886 pub fn r#get_vmo_info(
887 &self,
888 mut payload: AllocatorGetVmoInfoRequest,
889 ___deadline: zx::MonotonicInstant,
890 ) -> Result<AllocatorGetVmoInfoResult, fidl::Error> {
891 let _response = self.client.send_query::<
892 AllocatorGetVmoInfoRequest,
893 fidl::encoding::FlexibleResultType<AllocatorGetVmoInfoResponse, Error>,
894 AllocatorMarker,
895 >(
896 &mut payload,
897 0x21a881120aa0ddf9,
898 fidl::encoding::DynamicFlags::FLEXIBLE,
899 ___deadline,
900 )?
901 .into_result::<AllocatorMarker>("get_vmo_info")?;
902 Ok(_response.map(|x| x))
903 }
904}
905
906#[cfg(target_os = "fuchsia")]
907impl From<AllocatorSynchronousProxy> for zx::NullableHandle {
908 fn from(value: AllocatorSynchronousProxy) -> Self {
909 value.into_channel().into()
910 }
911}
912
913#[cfg(target_os = "fuchsia")]
914impl From<fidl::Channel> for AllocatorSynchronousProxy {
915 fn from(value: fidl::Channel) -> Self {
916 Self::new(value)
917 }
918}
919
920#[cfg(target_os = "fuchsia")]
921impl fidl::endpoints::FromClient for AllocatorSynchronousProxy {
922 type Protocol = AllocatorMarker;
923
924 fn from_client(value: fidl::endpoints::ClientEnd<AllocatorMarker>) -> Self {
925 Self::new(value.into_channel())
926 }
927}
928
929#[derive(Debug, Clone)]
930pub struct AllocatorProxy {
931 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
932}
933
934impl fidl::endpoints::Proxy for AllocatorProxy {
935 type Protocol = AllocatorMarker;
936
937 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
938 Self::new(inner)
939 }
940
941 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
942 self.client.into_channel().map_err(|client| Self { client })
943 }
944
945 fn as_channel(&self) -> &::fidl::AsyncChannel {
946 self.client.as_channel()
947 }
948}
949
950impl AllocatorProxy {
951 /// Create a new Proxy for fuchsia.sysmem2/Allocator.
952 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
953 let protocol_name = <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
954 Self { client: fidl::client::Client::new(channel, protocol_name) }
955 }
956
957 /// Get a Stream of events from the remote end of the protocol.
958 ///
959 /// # Panics
960 ///
961 /// Panics if the event stream was already taken.
962 pub fn take_event_stream(&self) -> AllocatorEventStream {
963 AllocatorEventStream { event_receiver: self.client.take_event_receiver() }
964 }
965
966 /// Allocates a buffer collection on behalf of a single client (aka
967 /// initiator) who is also the only participant (from the point of view of
968 /// sysmem).
969 ///
970 /// This call exists mainly for temp/testing purposes. This call skips the
971 /// [`fuchsia.sysmem2/BufferCollectionToken`] stage, so there's no way to
972 /// allow another participant to specify its constraints.
973 ///
974 /// Real clients are encouraged to use
975 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`] instead, and to
976 /// let relevant participants directly convey their own constraints to
977 /// sysmem by sending `BufferCollectionToken`s to those participants.
978 ///
979 /// + request `collection_request` The server end of the
980 /// [`fuchsia.sysmem2/BufferCollection`].
981 pub fn r#allocate_non_shared_collection(
982 &self,
983 mut payload: AllocatorAllocateNonSharedCollectionRequest,
984 ) -> Result<(), fidl::Error> {
985 AllocatorProxyInterface::r#allocate_non_shared_collection(self, payload)
986 }
987
988 /// Creates a root [`fuchsia.sysmem2/BufferCollectionToken`].
989 ///
990 /// The `BufferCollectionToken` can be "duplicated" for distribution to
991 /// participants by using
992 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`]. Each
993 /// `BufferCollectionToken` can be converted into a
994 /// [`fuchsia.sysmem2.BufferCollection`] using
995 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`].
996 ///
997 /// Buffer constraints can be set via
998 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
999 ///
1000 /// Success/failure to populate the buffer collection with buffers can be
1001 /// determined from
1002 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
1003 ///
1004 /// Closing the client end of a `BufferCollectionToken` or
1005 /// `BufferCollection` (without `Release` first) will fail all client ends
1006 /// in the same failure domain, which by default is all client ends of the
1007 /// buffer collection. See
1008 /// [`fuchsia.sysmem2/BufferCollection.SetDispensable`] and
1009 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`] for ways to create
1010 /// separate failure domains within a buffer collection.
1011 pub fn r#allocate_shared_collection(
1012 &self,
1013 mut payload: AllocatorAllocateSharedCollectionRequest,
1014 ) -> Result<(), fidl::Error> {
1015 AllocatorProxyInterface::r#allocate_shared_collection(self, payload)
1016 }
1017
1018 /// Convert a [`fuchsia.sysmem2/BufferCollectionToken`] into a
1019 /// [`fuchsia.sysmem2/BufferCollection`].
1020 ///
1021 /// At the time of sending this message, the buffer collection hasn't yet
1022 /// been populated with buffers - the participant must first also send
1023 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] via the
1024 /// `BufferCollection` client end.
1025 ///
1026 /// All `BufferCollectionToken`(s) duplicated from a root
1027 /// `BufferCollectionToken` (created via `AllocateSharedCollection`) must be
1028 /// "turned in" via `BindSharedCollection` (or `Release`ed), and all
1029 /// existing `BufferCollection` client ends must have sent `SetConstraints`
1030 /// before the logical BufferCollection will be populated with buffers (or
1031 /// will fail if the overall set of constraints can't be satisfied).
1032 ///
1033 /// + request `token` The client endpoint of a channel whose server end was
1034 /// sent to sysmem using
1035 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`] or whose server
1036 /// end was sent to sysmem using
1037 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`]. The token is
1038 /// being "turned in" in exchange for a
1039 /// [`fuchsia.sysmem2/BufferCollection`].
1040 /// + request `buffer_collection_request` The server end of a
1041 /// [`fuchsia.sysmem2/BufferCollection`] channel. The sender retains the
1042 /// client end. The `BufferCollection` channel is a single participant's
1043 /// connection to the logical buffer collection. Typically there will be
1044 /// other participants with their own `BufferCollection` channel to the
1045 /// logical buffer collection.
1046 pub fn r#bind_shared_collection(
1047 &self,
1048 mut payload: AllocatorBindSharedCollectionRequest,
1049 ) -> Result<(), fidl::Error> {
1050 AllocatorProxyInterface::r#bind_shared_collection(self, payload)
1051 }
1052
1053 /// Checks whether a [`fuchsia.sysmem2/BufferCollectionToken`] is known to
1054 /// the sysmem server.
1055 ///
1056 /// With this call, the client can determine whether an incoming token is a
1057 /// real sysmem token that is known to the sysmem server, without any risk
1058 /// of getting stuck waiting forever on a potentially fake token to complete
1059 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] or
1060 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] (or any other two-way
1061 /// FIDL message). In cases where the client trusts the source of the token
1062 /// to provide a real token, this call is not typically needed outside of
1063 /// debugging.
1064 ///
1065 /// If the validate fails sometimes but succeeds other times, the source of
1066 /// the token may itself not be calling
1067 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] or
1068 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after creating/duplicating the
1069 /// token but before sending the token to the current client. It may be more
1070 /// convenient for the source to use
1071 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] to duplicate
1072 /// token(s), since that call has the sync step built in. Or, the buffer
1073 /// collection may be failing before this call is processed by the sysmem
1074 /// server, as buffer collection failure cleans up sysmem's tracking of
1075 /// associated tokens.
1076 ///
1077 /// This call has no effect on any token.
1078 ///
1079 /// + request `token_server_koid` The koid of the server end of a channel
1080 /// that might be a BufferCollectionToken channel. This can be obtained
1081 /// via `zx_object_get_info` `ZX_INFO_HANDLE_BASIC` `related_koid`.
1082 /// - response `is_known` true means sysmem knew of the token at the time
1083 /// sysmem processed the request, but doesn't guarantee that the token is
1084 /// still valid by the time the client receives the reply. What it does
1085 /// guarantee is that the token at least was a real token, so a two-way
1086 /// call to the token won't stall forever (will fail or succeed fairly
1087 /// quickly, not stall). This can already be known implicitly if the
1088 /// source of the token can be trusted to provide a real token. A false
1089 /// value means the token wasn't known to sysmem at the time sysmem
1090 /// processed this call, but the token may have previously been valid, or
1091 /// may yet become valid. Or if the sender of the token isn't trusted to
1092 /// provide a real token, the token may be fake. It's the responsibility
1093 /// of the sender to sync with sysmem to ensure that previously
1094 /// created/duplicated token(s) are known to sysmem, before sending the
1095 /// token(s) to other participants.
1096 pub fn r#validate_buffer_collection_token(
1097 &self,
1098 mut payload: &AllocatorValidateBufferCollectionTokenRequest,
1099 ) -> fidl::client::QueryResponseFut<
1100 AllocatorValidateBufferCollectionTokenResponse,
1101 fidl::encoding::DefaultFuchsiaResourceDialect,
1102 > {
1103 AllocatorProxyInterface::r#validate_buffer_collection_token(self, payload)
1104 }
1105
1106 /// Set information about the current client that can be used by sysmem to
1107 /// help diagnose leaking memory and allocation stalls waiting for a
1108 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
1109 ///
1110 /// This sets the debug client info on all [`fuchsia.sysmem2/Node`](s)
1111 /// subsequently created by this this [`fuchsia.sysmem2/Allocator`]
1112 /// including any [`fuchsia.sysmem2/BufferCollection`](s) created via
1113 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] (in the absence of
1114 /// any prior call to [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`],
1115 /// these `BufferCollection`(s) have the same initial debug client info as
1116 /// the token turned in to create the `BufferCollection`).
1117 ///
1118 /// This info can be subsequently overridden on a per-`Node` basis by
1119 /// sending [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
1120 ///
1121 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
1122 /// `Allocator` is the most efficient way to ensure that all
1123 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
1124 /// set, and is also more efficient than separately sending the same debug
1125 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
1126 /// created [`fuchsia.sysmem2/Node`].
1127 ///
1128 /// + request `name` This can be an arbitrary string, but the current
1129 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
1130 /// + request `id` This can be an arbitrary id, but the current process ID
1131 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
1132 pub fn r#set_debug_client_info(
1133 &self,
1134 mut payload: &AllocatorSetDebugClientInfoRequest,
1135 ) -> Result<(), fidl::Error> {
1136 AllocatorProxyInterface::r#set_debug_client_info(self, payload)
1137 }
1138
1139 /// Given a handle to a sysmem-provided VMO, this returns additional info
1140 /// about the corresponding sysmem logical buffer.
1141 ///
1142 /// Most callers will duplicate a VMO handle first and send the duplicate to
1143 /// this call.
1144 ///
1145 /// If the client has created a child VMO of a sysmem-provided VMO, that
1146 /// child VMO isn't considered a "sysmem VMO" for purposes of this call.
1147 ///
1148 /// + request `vmo` A handle to a sysmem-provided VMO (or see errors).
1149 /// + request `need_weak` Iff set to true, the response will have weak_vmo
1150 /// set to a weak VMO for the buffer, regardless of whether `vmo` in the
1151 /// request was weak or strong.
1152 /// - response `buffer_collection_id` The buffer collection ID, which is
1153 /// unique per logical buffer collection per boot.
1154 /// - response `buffer_index` The buffer index of the buffer within the
1155 /// buffer collection. This is the same as the index of the buffer within
1156 /// [`fuchsia.sysmem2/BufferCollectionInfo.buffers`]. The `buffer_index`
1157 /// is the same for all sysmem-delivered VMOs corresponding to the same
1158 /// logical buffer, even if the VMO koids differ. The `buffer_index` is
1159 /// only unique across buffers of a buffer collection. For a given buffer,
1160 /// the combination of `buffer_collection_id` and `buffer_index` is unique
1161 /// per boot.
1162 /// - response `close_weak_asap` Iff `vmo` is a handle to a weak sysmem VMO
1163 /// OR need_weak is set to true, the `close_weak_asap` field will be set
1164 /// in the response. This handle will signal `ZX_EVENTPAIR_PEER_CLOSED`
1165 /// when all weak VMO handles to the buffer should be closed as soon as
1166 /// possible. This is signalled shortly after all strong sysmem VMOs to
1167 /// the buffer are closed (including any held indirectly via strong
1168 /// `BufferCollectionToken` or strong `BufferCollection`). Failure to
1169 /// close all weak sysmem VMO handles to the buffer quickly upon
1170 /// `ZX_EVENTPAIR_PEER_CLOSED` is considered a VMO leak caused by the
1171 /// client still holding a weak sysmem VMO handle and results in loud
1172 /// complaints to the log by sysmem (after a delay). The buffers of a
1173 /// collection can be freed independently of each other. The
1174 /// `ZX_EVENTPAIR_PEER_CLOSED` may already be signalled before the
1175 /// response arrives at the client. A client that isn't prepared to
1176 /// directly handle weak sysmem VMOs and waiting on close_weak_asap, on
1177 /// seeing this field set in response to a request that had need_weak
1178 /// un-set, typically should ignore the fact that the vmo handle was a
1179 /// weak vmo handle; typically another participant that's also a client of
1180 /// this participant via some other protocol has taken responsibility for
1181 /// ensuring that this participant will close all handles to the buffer,
1182 /// typically by shutting down this participant's context holding a vmo
1183 /// handle in some other way. That said, it is not harmful for both
1184 /// participants to directly handle close_weak_asap, even if one
1185 /// participant can take responsibility for handling close_weak_asap. See
1186 /// also `[fuchsia.sysmem2/Node.SetWeakOk]` for_child_nodes_also.
1187 /// - response `weak_vmo` This field is set in the response iff the request
1188 /// had `need_weak` set to true. When set, this is a weak VMO handle to
1189 /// the same buffer as `vmo` in the request, but may not have the same
1190 /// koid as `vmo` had (this applies regardless of whether `vmo` was strong
1191 /// or weak).
1192 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` - the vmo isn't a sysmem
1193 /// VMO. Both strong and weak sysmem VMOs can be passed to this call, and
1194 /// the VMO handle passed in to this call itself keeps the VMO's info
1195 /// alive for purposes of responding to this call. Because of this,
1196 /// ZX_ERR_NOT_FOUND errors are unambiguous (even if there are no other
1197 /// handles to the VMO when calling; even if other handles are closed
1198 /// before the GetVmoInfo response arrives at the client).
1199 /// * error `[fuchsia.sysmem2/Error.UNSPECIFIED]` The request failed for an
1200 /// unspecified reason. See the log for more info.
1201 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The vmo field
1202 /// wasn't set, or there was some other problem with the request field(s).
1203 /// See the log.
1204 pub fn r#get_vmo_info(
1205 &self,
1206 mut payload: AllocatorGetVmoInfoRequest,
1207 ) -> fidl::client::QueryResponseFut<
1208 AllocatorGetVmoInfoResult,
1209 fidl::encoding::DefaultFuchsiaResourceDialect,
1210 > {
1211 AllocatorProxyInterface::r#get_vmo_info(self, payload)
1212 }
1213}
1214
1215impl AllocatorProxyInterface for AllocatorProxy {
1216 fn r#allocate_non_shared_collection(
1217 &self,
1218 mut payload: AllocatorAllocateNonSharedCollectionRequest,
1219 ) -> Result<(), fidl::Error> {
1220 self.client.send::<AllocatorAllocateNonSharedCollectionRequest>(
1221 &mut payload,
1222 0x5ca681f025a80e44,
1223 fidl::encoding::DynamicFlags::FLEXIBLE,
1224 )
1225 }
1226
1227 fn r#allocate_shared_collection(
1228 &self,
1229 mut payload: AllocatorAllocateSharedCollectionRequest,
1230 ) -> Result<(), fidl::Error> {
1231 self.client.send::<AllocatorAllocateSharedCollectionRequest>(
1232 &mut payload,
1233 0x11a19ff51f0b49c1,
1234 fidl::encoding::DynamicFlags::FLEXIBLE,
1235 )
1236 }
1237
1238 fn r#bind_shared_collection(
1239 &self,
1240 mut payload: AllocatorBindSharedCollectionRequest,
1241 ) -> Result<(), fidl::Error> {
1242 self.client.send::<AllocatorBindSharedCollectionRequest>(
1243 &mut payload,
1244 0x550916b0dc1d5b4e,
1245 fidl::encoding::DynamicFlags::FLEXIBLE,
1246 )
1247 }
1248
1249 type ValidateBufferCollectionTokenResponseFut = fidl::client::QueryResponseFut<
1250 AllocatorValidateBufferCollectionTokenResponse,
1251 fidl::encoding::DefaultFuchsiaResourceDialect,
1252 >;
1253 fn r#validate_buffer_collection_token(
1254 &self,
1255 mut payload: &AllocatorValidateBufferCollectionTokenRequest,
1256 ) -> Self::ValidateBufferCollectionTokenResponseFut {
1257 fn _decode(
1258 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
1259 ) -> Result<AllocatorValidateBufferCollectionTokenResponse, fidl::Error> {
1260 let _response = fidl::client::decode_transaction_body::<
1261 fidl::encoding::FlexibleType<AllocatorValidateBufferCollectionTokenResponse>,
1262 fidl::encoding::DefaultFuchsiaResourceDialect,
1263 0x4c5ee91b02a7e68d,
1264 >(_buf?)?
1265 .into_result::<AllocatorMarker>("validate_buffer_collection_token")?;
1266 Ok(_response)
1267 }
1268 self.client.send_query_and_decode::<
1269 AllocatorValidateBufferCollectionTokenRequest,
1270 AllocatorValidateBufferCollectionTokenResponse,
1271 >(
1272 payload,
1273 0x4c5ee91b02a7e68d,
1274 fidl::encoding::DynamicFlags::FLEXIBLE,
1275 _decode,
1276 )
1277 }
1278
1279 fn r#set_debug_client_info(
1280 &self,
1281 mut payload: &AllocatorSetDebugClientInfoRequest,
1282 ) -> Result<(), fidl::Error> {
1283 self.client.send::<AllocatorSetDebugClientInfoRequest>(
1284 payload,
1285 0x6f68f19a3f509c4d,
1286 fidl::encoding::DynamicFlags::FLEXIBLE,
1287 )
1288 }
1289
1290 type GetVmoInfoResponseFut = fidl::client::QueryResponseFut<
1291 AllocatorGetVmoInfoResult,
1292 fidl::encoding::DefaultFuchsiaResourceDialect,
1293 >;
1294 fn r#get_vmo_info(
1295 &self,
1296 mut payload: AllocatorGetVmoInfoRequest,
1297 ) -> Self::GetVmoInfoResponseFut {
1298 fn _decode(
1299 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
1300 ) -> Result<AllocatorGetVmoInfoResult, fidl::Error> {
1301 let _response = fidl::client::decode_transaction_body::<
1302 fidl::encoding::FlexibleResultType<AllocatorGetVmoInfoResponse, Error>,
1303 fidl::encoding::DefaultFuchsiaResourceDialect,
1304 0x21a881120aa0ddf9,
1305 >(_buf?)?
1306 .into_result::<AllocatorMarker>("get_vmo_info")?;
1307 Ok(_response.map(|x| x))
1308 }
1309 self.client.send_query_and_decode::<AllocatorGetVmoInfoRequest, AllocatorGetVmoInfoResult>(
1310 &mut payload,
1311 0x21a881120aa0ddf9,
1312 fidl::encoding::DynamicFlags::FLEXIBLE,
1313 _decode,
1314 )
1315 }
1316}
1317
1318pub struct AllocatorEventStream {
1319 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
1320}
1321
1322impl std::marker::Unpin for AllocatorEventStream {}
1323
1324impl futures::stream::FusedStream for AllocatorEventStream {
1325 fn is_terminated(&self) -> bool {
1326 self.event_receiver.is_terminated()
1327 }
1328}
1329
1330impl futures::Stream for AllocatorEventStream {
1331 type Item = Result<AllocatorEvent, fidl::Error>;
1332
1333 fn poll_next(
1334 mut self: std::pin::Pin<&mut Self>,
1335 cx: &mut std::task::Context<'_>,
1336 ) -> std::task::Poll<Option<Self::Item>> {
1337 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
1338 &mut self.event_receiver,
1339 cx
1340 )?) {
1341 Some(buf) => std::task::Poll::Ready(Some(AllocatorEvent::decode(buf))),
1342 None => std::task::Poll::Ready(None),
1343 }
1344 }
1345}
1346
1347#[derive(Debug)]
1348pub enum AllocatorEvent {
1349 #[non_exhaustive]
1350 _UnknownEvent {
1351 /// Ordinal of the event that was sent.
1352 ordinal: u64,
1353 },
1354}
1355
1356impl AllocatorEvent {
1357 /// Decodes a message buffer as a [`AllocatorEvent`].
1358 fn decode(
1359 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
1360 ) -> Result<AllocatorEvent, fidl::Error> {
1361 let (bytes, _handles) = buf.split_mut();
1362 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
1363 debug_assert_eq!(tx_header.tx_id, 0);
1364 match tx_header.ordinal {
1365 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
1366 Ok(AllocatorEvent::_UnknownEvent { ordinal: tx_header.ordinal })
1367 }
1368 _ => Err(fidl::Error::UnknownOrdinal {
1369 ordinal: tx_header.ordinal,
1370 protocol_name: <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1371 }),
1372 }
1373 }
1374}
1375
1376/// A Stream of incoming requests for fuchsia.sysmem2/Allocator.
1377pub struct AllocatorRequestStream {
1378 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1379 is_terminated: bool,
1380}
1381
1382impl std::marker::Unpin for AllocatorRequestStream {}
1383
1384impl futures::stream::FusedStream for AllocatorRequestStream {
1385 fn is_terminated(&self) -> bool {
1386 self.is_terminated
1387 }
1388}
1389
1390impl fidl::endpoints::RequestStream for AllocatorRequestStream {
1391 type Protocol = AllocatorMarker;
1392 type ControlHandle = AllocatorControlHandle;
1393
1394 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
1395 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
1396 }
1397
1398 fn control_handle(&self) -> Self::ControlHandle {
1399 AllocatorControlHandle { inner: self.inner.clone() }
1400 }
1401
1402 fn into_inner(
1403 self,
1404 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
1405 {
1406 (self.inner, self.is_terminated)
1407 }
1408
1409 fn from_inner(
1410 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1411 is_terminated: bool,
1412 ) -> Self {
1413 Self { inner, is_terminated }
1414 }
1415}
1416
1417impl futures::Stream for AllocatorRequestStream {
1418 type Item = Result<AllocatorRequest, fidl::Error>;
1419
1420 fn poll_next(
1421 mut self: std::pin::Pin<&mut Self>,
1422 cx: &mut std::task::Context<'_>,
1423 ) -> std::task::Poll<Option<Self::Item>> {
1424 let this = &mut *self;
1425 if this.inner.check_shutdown(cx) {
1426 this.is_terminated = true;
1427 return std::task::Poll::Ready(None);
1428 }
1429 if this.is_terminated {
1430 panic!("polled AllocatorRequestStream after completion");
1431 }
1432 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
1433 |bytes, handles| {
1434 match this.inner.channel().read_etc(cx, bytes, handles) {
1435 std::task::Poll::Ready(Ok(())) => {}
1436 std::task::Poll::Pending => return std::task::Poll::Pending,
1437 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
1438 this.is_terminated = true;
1439 return std::task::Poll::Ready(None);
1440 }
1441 std::task::Poll::Ready(Err(e)) => {
1442 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
1443 e.into(),
1444 ))));
1445 }
1446 }
1447
1448 // A message has been received from the channel
1449 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
1450
1451 std::task::Poll::Ready(Some(match header.ordinal {
1452 0x5ca681f025a80e44 => {
1453 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
1454 let mut req = fidl::new_empty!(
1455 AllocatorAllocateNonSharedCollectionRequest,
1456 fidl::encoding::DefaultFuchsiaResourceDialect
1457 );
1458 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorAllocateNonSharedCollectionRequest>(&header, _body_bytes, handles, &mut req)?;
1459 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
1460 Ok(AllocatorRequest::AllocateNonSharedCollection {
1461 payload: req,
1462 control_handle,
1463 })
1464 }
1465 0x11a19ff51f0b49c1 => {
1466 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
1467 let mut req = fidl::new_empty!(
1468 AllocatorAllocateSharedCollectionRequest,
1469 fidl::encoding::DefaultFuchsiaResourceDialect
1470 );
1471 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorAllocateSharedCollectionRequest>(&header, _body_bytes, handles, &mut req)?;
1472 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
1473 Ok(AllocatorRequest::AllocateSharedCollection {
1474 payload: req,
1475 control_handle,
1476 })
1477 }
1478 0x550916b0dc1d5b4e => {
1479 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
1480 let mut req = fidl::new_empty!(
1481 AllocatorBindSharedCollectionRequest,
1482 fidl::encoding::DefaultFuchsiaResourceDialect
1483 );
1484 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorBindSharedCollectionRequest>(&header, _body_bytes, handles, &mut req)?;
1485 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
1486 Ok(AllocatorRequest::BindSharedCollection { payload: req, control_handle })
1487 }
1488 0x4c5ee91b02a7e68d => {
1489 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
1490 let mut req = fidl::new_empty!(
1491 AllocatorValidateBufferCollectionTokenRequest,
1492 fidl::encoding::DefaultFuchsiaResourceDialect
1493 );
1494 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorValidateBufferCollectionTokenRequest>(&header, _body_bytes, handles, &mut req)?;
1495 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
1496 Ok(AllocatorRequest::ValidateBufferCollectionToken {
1497 payload: req,
1498 responder: AllocatorValidateBufferCollectionTokenResponder {
1499 control_handle: std::mem::ManuallyDrop::new(control_handle),
1500 tx_id: header.tx_id,
1501 },
1502 })
1503 }
1504 0x6f68f19a3f509c4d => {
1505 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
1506 let mut req = fidl::new_empty!(
1507 AllocatorSetDebugClientInfoRequest,
1508 fidl::encoding::DefaultFuchsiaResourceDialect
1509 );
1510 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
1511 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
1512 Ok(AllocatorRequest::SetDebugClientInfo { payload: req, control_handle })
1513 }
1514 0x21a881120aa0ddf9 => {
1515 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
1516 let mut req = fidl::new_empty!(
1517 AllocatorGetVmoInfoRequest,
1518 fidl::encoding::DefaultFuchsiaResourceDialect
1519 );
1520 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorGetVmoInfoRequest>(&header, _body_bytes, handles, &mut req)?;
1521 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
1522 Ok(AllocatorRequest::GetVmoInfo {
1523 payload: req,
1524 responder: AllocatorGetVmoInfoResponder {
1525 control_handle: std::mem::ManuallyDrop::new(control_handle),
1526 tx_id: header.tx_id,
1527 },
1528 })
1529 }
1530 _ if header.tx_id == 0
1531 && header
1532 .dynamic_flags()
1533 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
1534 {
1535 Ok(AllocatorRequest::_UnknownMethod {
1536 ordinal: header.ordinal,
1537 control_handle: AllocatorControlHandle { inner: this.inner.clone() },
1538 method_type: fidl::MethodType::OneWay,
1539 })
1540 }
1541 _ if header
1542 .dynamic_flags()
1543 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
1544 {
1545 this.inner.send_framework_err(
1546 fidl::encoding::FrameworkErr::UnknownMethod,
1547 header.tx_id,
1548 header.ordinal,
1549 header.dynamic_flags(),
1550 (bytes, handles),
1551 )?;
1552 Ok(AllocatorRequest::_UnknownMethod {
1553 ordinal: header.ordinal,
1554 control_handle: AllocatorControlHandle { inner: this.inner.clone() },
1555 method_type: fidl::MethodType::TwoWay,
1556 })
1557 }
1558 _ => Err(fidl::Error::UnknownOrdinal {
1559 ordinal: header.ordinal,
1560 protocol_name:
1561 <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1562 }),
1563 }))
1564 },
1565 )
1566 }
1567}
1568
1569/// Allocates system memory buffers.
1570///
1571/// Epitaphs are not used in this protocol.
1572#[derive(Debug)]
1573pub enum AllocatorRequest {
1574 /// Allocates a buffer collection on behalf of a single client (aka
1575 /// initiator) who is also the only participant (from the point of view of
1576 /// sysmem).
1577 ///
1578 /// This call exists mainly for temp/testing purposes. This call skips the
1579 /// [`fuchsia.sysmem2/BufferCollectionToken`] stage, so there's no way to
1580 /// allow another participant to specify its constraints.
1581 ///
1582 /// Real clients are encouraged to use
1583 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`] instead, and to
1584 /// let relevant participants directly convey their own constraints to
1585 /// sysmem by sending `BufferCollectionToken`s to those participants.
1586 ///
1587 /// + request `collection_request` The server end of the
1588 /// [`fuchsia.sysmem2/BufferCollection`].
1589 AllocateNonSharedCollection {
1590 payload: AllocatorAllocateNonSharedCollectionRequest,
1591 control_handle: AllocatorControlHandle,
1592 },
1593 /// Creates a root [`fuchsia.sysmem2/BufferCollectionToken`].
1594 ///
1595 /// The `BufferCollectionToken` can be "duplicated" for distribution to
1596 /// participants by using
1597 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`]. Each
1598 /// `BufferCollectionToken` can be converted into a
1599 /// [`fuchsia.sysmem2.BufferCollection`] using
1600 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`].
1601 ///
1602 /// Buffer constraints can be set via
1603 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
1604 ///
1605 /// Success/failure to populate the buffer collection with buffers can be
1606 /// determined from
1607 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
1608 ///
1609 /// Closing the client end of a `BufferCollectionToken` or
1610 /// `BufferCollection` (without `Release` first) will fail all client ends
1611 /// in the same failure domain, which by default is all client ends of the
1612 /// buffer collection. See
1613 /// [`fuchsia.sysmem2/BufferCollection.SetDispensable`] and
1614 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`] for ways to create
1615 /// separate failure domains within a buffer collection.
1616 AllocateSharedCollection {
1617 payload: AllocatorAllocateSharedCollectionRequest,
1618 control_handle: AllocatorControlHandle,
1619 },
1620 /// Convert a [`fuchsia.sysmem2/BufferCollectionToken`] into a
1621 /// [`fuchsia.sysmem2/BufferCollection`].
1622 ///
1623 /// At the time of sending this message, the buffer collection hasn't yet
1624 /// been populated with buffers - the participant must first also send
1625 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] via the
1626 /// `BufferCollection` client end.
1627 ///
1628 /// All `BufferCollectionToken`(s) duplicated from a root
1629 /// `BufferCollectionToken` (created via `AllocateSharedCollection`) must be
1630 /// "turned in" via `BindSharedCollection` (or `Release`ed), and all
1631 /// existing `BufferCollection` client ends must have sent `SetConstraints`
1632 /// before the logical BufferCollection will be populated with buffers (or
1633 /// will fail if the overall set of constraints can't be satisfied).
1634 ///
1635 /// + request `token` The client endpoint of a channel whose server end was
1636 /// sent to sysmem using
1637 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`] or whose server
1638 /// end was sent to sysmem using
1639 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`]. The token is
1640 /// being "turned in" in exchange for a
1641 /// [`fuchsia.sysmem2/BufferCollection`].
1642 /// + request `buffer_collection_request` The server end of a
1643 /// [`fuchsia.sysmem2/BufferCollection`] channel. The sender retains the
1644 /// client end. The `BufferCollection` channel is a single participant's
1645 /// connection to the logical buffer collection. Typically there will be
1646 /// other participants with their own `BufferCollection` channel to the
1647 /// logical buffer collection.
1648 BindSharedCollection {
1649 payload: AllocatorBindSharedCollectionRequest,
1650 control_handle: AllocatorControlHandle,
1651 },
1652 /// Checks whether a [`fuchsia.sysmem2/BufferCollectionToken`] is known to
1653 /// the sysmem server.
1654 ///
1655 /// With this call, the client can determine whether an incoming token is a
1656 /// real sysmem token that is known to the sysmem server, without any risk
1657 /// of getting stuck waiting forever on a potentially fake token to complete
1658 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] or
1659 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] (or any other two-way
1660 /// FIDL message). In cases where the client trusts the source of the token
1661 /// to provide a real token, this call is not typically needed outside of
1662 /// debugging.
1663 ///
1664 /// If the validate fails sometimes but succeeds other times, the source of
1665 /// the token may itself not be calling
1666 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] or
1667 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after creating/duplicating the
1668 /// token but before sending the token to the current client. It may be more
1669 /// convenient for the source to use
1670 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] to duplicate
1671 /// token(s), since that call has the sync step built in. Or, the buffer
1672 /// collection may be failing before this call is processed by the sysmem
1673 /// server, as buffer collection failure cleans up sysmem's tracking of
1674 /// associated tokens.
1675 ///
1676 /// This call has no effect on any token.
1677 ///
1678 /// + request `token_server_koid` The koid of the server end of a channel
1679 /// that might be a BufferCollectionToken channel. This can be obtained
1680 /// via `zx_object_get_info` `ZX_INFO_HANDLE_BASIC` `related_koid`.
1681 /// - response `is_known` true means sysmem knew of the token at the time
1682 /// sysmem processed the request, but doesn't guarantee that the token is
1683 /// still valid by the time the client receives the reply. What it does
1684 /// guarantee is that the token at least was a real token, so a two-way
1685 /// call to the token won't stall forever (will fail or succeed fairly
1686 /// quickly, not stall). This can already be known implicitly if the
1687 /// source of the token can be trusted to provide a real token. A false
1688 /// value means the token wasn't known to sysmem at the time sysmem
1689 /// processed this call, but the token may have previously been valid, or
1690 /// may yet become valid. Or if the sender of the token isn't trusted to
1691 /// provide a real token, the token may be fake. It's the responsibility
1692 /// of the sender to sync with sysmem to ensure that previously
1693 /// created/duplicated token(s) are known to sysmem, before sending the
1694 /// token(s) to other participants.
1695 ValidateBufferCollectionToken {
1696 payload: AllocatorValidateBufferCollectionTokenRequest,
1697 responder: AllocatorValidateBufferCollectionTokenResponder,
1698 },
1699 /// Set information about the current client that can be used by sysmem to
1700 /// help diagnose leaking memory and allocation stalls waiting for a
1701 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
1702 ///
1703 /// This sets the debug client info on all [`fuchsia.sysmem2/Node`](s)
1704 /// subsequently created by this this [`fuchsia.sysmem2/Allocator`]
1705 /// including any [`fuchsia.sysmem2/BufferCollection`](s) created via
1706 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] (in the absence of
1707 /// any prior call to [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`],
1708 /// these `BufferCollection`(s) have the same initial debug client info as
1709 /// the token turned in to create the `BufferCollection`).
1710 ///
1711 /// This info can be subsequently overridden on a per-`Node` basis by
1712 /// sending [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
1713 ///
1714 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
1715 /// `Allocator` is the most efficient way to ensure that all
1716 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
1717 /// set, and is also more efficient than separately sending the same debug
1718 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
1719 /// created [`fuchsia.sysmem2/Node`].
1720 ///
1721 /// + request `name` This can be an arbitrary string, but the current
1722 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
1723 /// + request `id` This can be an arbitrary id, but the current process ID
1724 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
1725 SetDebugClientInfo {
1726 payload: AllocatorSetDebugClientInfoRequest,
1727 control_handle: AllocatorControlHandle,
1728 },
1729 /// Given a handle to a sysmem-provided VMO, this returns additional info
1730 /// about the corresponding sysmem logical buffer.
1731 ///
1732 /// Most callers will duplicate a VMO handle first and send the duplicate to
1733 /// this call.
1734 ///
1735 /// If the client has created a child VMO of a sysmem-provided VMO, that
1736 /// child VMO isn't considered a "sysmem VMO" for purposes of this call.
1737 ///
1738 /// + request `vmo` A handle to a sysmem-provided VMO (or see errors).
1739 /// + request `need_weak` Iff set to true, the response will have weak_vmo
1740 /// set to a weak VMO for the buffer, regardless of whether `vmo` in the
1741 /// request was weak or strong.
1742 /// - response `buffer_collection_id` The buffer collection ID, which is
1743 /// unique per logical buffer collection per boot.
1744 /// - response `buffer_index` The buffer index of the buffer within the
1745 /// buffer collection. This is the same as the index of the buffer within
1746 /// [`fuchsia.sysmem2/BufferCollectionInfo.buffers`]. The `buffer_index`
1747 /// is the same for all sysmem-delivered VMOs corresponding to the same
1748 /// logical buffer, even if the VMO koids differ. The `buffer_index` is
1749 /// only unique across buffers of a buffer collection. For a given buffer,
1750 /// the combination of `buffer_collection_id` and `buffer_index` is unique
1751 /// per boot.
1752 /// - response `close_weak_asap` Iff `vmo` is a handle to a weak sysmem VMO
1753 /// OR need_weak is set to true, the `close_weak_asap` field will be set
1754 /// in the response. This handle will signal `ZX_EVENTPAIR_PEER_CLOSED`
1755 /// when all weak VMO handles to the buffer should be closed as soon as
1756 /// possible. This is signalled shortly after all strong sysmem VMOs to
1757 /// the buffer are closed (including any held indirectly via strong
1758 /// `BufferCollectionToken` or strong `BufferCollection`). Failure to
1759 /// close all weak sysmem VMO handles to the buffer quickly upon
1760 /// `ZX_EVENTPAIR_PEER_CLOSED` is considered a VMO leak caused by the
1761 /// client still holding a weak sysmem VMO handle and results in loud
1762 /// complaints to the log by sysmem (after a delay). The buffers of a
1763 /// collection can be freed independently of each other. The
1764 /// `ZX_EVENTPAIR_PEER_CLOSED` may already be signalled before the
1765 /// response arrives at the client. A client that isn't prepared to
1766 /// directly handle weak sysmem VMOs and waiting on close_weak_asap, on
1767 /// seeing this field set in response to a request that had need_weak
1768 /// un-set, typically should ignore the fact that the vmo handle was a
1769 /// weak vmo handle; typically another participant that's also a client of
1770 /// this participant via some other protocol has taken responsibility for
1771 /// ensuring that this participant will close all handles to the buffer,
1772 /// typically by shutting down this participant's context holding a vmo
1773 /// handle in some other way. That said, it is not harmful for both
1774 /// participants to directly handle close_weak_asap, even if one
1775 /// participant can take responsibility for handling close_weak_asap. See
1776 /// also `[fuchsia.sysmem2/Node.SetWeakOk]` for_child_nodes_also.
1777 /// - response `weak_vmo` This field is set in the response iff the request
1778 /// had `need_weak` set to true. When set, this is a weak VMO handle to
1779 /// the same buffer as `vmo` in the request, but may not have the same
1780 /// koid as `vmo` had (this applies regardless of whether `vmo` was strong
1781 /// or weak).
1782 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` - the vmo isn't a sysmem
1783 /// VMO. Both strong and weak sysmem VMOs can be passed to this call, and
1784 /// the VMO handle passed in to this call itself keeps the VMO's info
1785 /// alive for purposes of responding to this call. Because of this,
1786 /// ZX_ERR_NOT_FOUND errors are unambiguous (even if there are no other
1787 /// handles to the VMO when calling; even if other handles are closed
1788 /// before the GetVmoInfo response arrives at the client).
1789 /// * error `[fuchsia.sysmem2/Error.UNSPECIFIED]` The request failed for an
1790 /// unspecified reason. See the log for more info.
1791 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The vmo field
1792 /// wasn't set, or there was some other problem with the request field(s).
1793 /// See the log.
1794 GetVmoInfo { payload: AllocatorGetVmoInfoRequest, responder: AllocatorGetVmoInfoResponder },
1795 /// An interaction was received which does not match any known method.
1796 #[non_exhaustive]
1797 _UnknownMethod {
1798 /// Ordinal of the method that was called.
1799 ordinal: u64,
1800 control_handle: AllocatorControlHandle,
1801 method_type: fidl::MethodType,
1802 },
1803}
1804
1805impl AllocatorRequest {
1806 #[allow(irrefutable_let_patterns)]
1807 pub fn into_allocate_non_shared_collection(
1808 self,
1809 ) -> Option<(AllocatorAllocateNonSharedCollectionRequest, AllocatorControlHandle)> {
1810 if let AllocatorRequest::AllocateNonSharedCollection { payload, control_handle } = self {
1811 Some((payload, control_handle))
1812 } else {
1813 None
1814 }
1815 }
1816
1817 #[allow(irrefutable_let_patterns)]
1818 pub fn into_allocate_shared_collection(
1819 self,
1820 ) -> Option<(AllocatorAllocateSharedCollectionRequest, AllocatorControlHandle)> {
1821 if let AllocatorRequest::AllocateSharedCollection { payload, control_handle } = self {
1822 Some((payload, control_handle))
1823 } else {
1824 None
1825 }
1826 }
1827
1828 #[allow(irrefutable_let_patterns)]
1829 pub fn into_bind_shared_collection(
1830 self,
1831 ) -> Option<(AllocatorBindSharedCollectionRequest, AllocatorControlHandle)> {
1832 if let AllocatorRequest::BindSharedCollection { payload, control_handle } = self {
1833 Some((payload, control_handle))
1834 } else {
1835 None
1836 }
1837 }
1838
1839 #[allow(irrefutable_let_patterns)]
1840 pub fn into_validate_buffer_collection_token(
1841 self,
1842 ) -> Option<(
1843 AllocatorValidateBufferCollectionTokenRequest,
1844 AllocatorValidateBufferCollectionTokenResponder,
1845 )> {
1846 if let AllocatorRequest::ValidateBufferCollectionToken { payload, responder } = self {
1847 Some((payload, responder))
1848 } else {
1849 None
1850 }
1851 }
1852
1853 #[allow(irrefutable_let_patterns)]
1854 pub fn into_set_debug_client_info(
1855 self,
1856 ) -> Option<(AllocatorSetDebugClientInfoRequest, AllocatorControlHandle)> {
1857 if let AllocatorRequest::SetDebugClientInfo { payload, control_handle } = self {
1858 Some((payload, control_handle))
1859 } else {
1860 None
1861 }
1862 }
1863
1864 #[allow(irrefutable_let_patterns)]
1865 pub fn into_get_vmo_info(
1866 self,
1867 ) -> Option<(AllocatorGetVmoInfoRequest, AllocatorGetVmoInfoResponder)> {
1868 if let AllocatorRequest::GetVmoInfo { payload, responder } = self {
1869 Some((payload, responder))
1870 } else {
1871 None
1872 }
1873 }
1874
1875 /// Name of the method defined in FIDL
1876 pub fn method_name(&self) -> &'static str {
1877 match *self {
1878 AllocatorRequest::AllocateNonSharedCollection { .. } => {
1879 "allocate_non_shared_collection"
1880 }
1881 AllocatorRequest::AllocateSharedCollection { .. } => "allocate_shared_collection",
1882 AllocatorRequest::BindSharedCollection { .. } => "bind_shared_collection",
1883 AllocatorRequest::ValidateBufferCollectionToken { .. } => {
1884 "validate_buffer_collection_token"
1885 }
1886 AllocatorRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
1887 AllocatorRequest::GetVmoInfo { .. } => "get_vmo_info",
1888 AllocatorRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
1889 "unknown one-way method"
1890 }
1891 AllocatorRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
1892 "unknown two-way method"
1893 }
1894 }
1895 }
1896}
1897
1898#[derive(Debug, Clone)]
1899pub struct AllocatorControlHandle {
1900 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1901}
1902
1903impl AllocatorControlHandle {
1904 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
1905 self.inner.shutdown_with_epitaph(status.into())
1906 }
1907}
1908
1909impl fidl::endpoints::ControlHandle for AllocatorControlHandle {
1910 fn shutdown(&self) {
1911 self.inner.shutdown()
1912 }
1913
1914 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
1915 self.inner.shutdown_with_epitaph(status)
1916 }
1917
1918 fn is_closed(&self) -> bool {
1919 self.inner.channel().is_closed()
1920 }
1921 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1922 self.inner.channel().on_closed()
1923 }
1924
1925 #[cfg(target_os = "fuchsia")]
1926 fn signal_peer(
1927 &self,
1928 clear_mask: zx::Signals,
1929 set_mask: zx::Signals,
1930 ) -> Result<(), zx_status::Status> {
1931 use fidl::Peered;
1932 self.inner.channel().signal_peer(clear_mask, set_mask)
1933 }
1934}
1935
1936impl AllocatorControlHandle {}
1937
1938#[must_use = "FIDL methods require a response to be sent"]
1939#[derive(Debug)]
1940pub struct AllocatorValidateBufferCollectionTokenResponder {
1941 control_handle: std::mem::ManuallyDrop<AllocatorControlHandle>,
1942 tx_id: u32,
1943}
1944
1945/// Set the the channel to be shutdown (see [`AllocatorControlHandle::shutdown`])
1946/// if the responder is dropped without sending a response, so that the client
1947/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1948impl std::ops::Drop for AllocatorValidateBufferCollectionTokenResponder {
1949 fn drop(&mut self) {
1950 self.control_handle.shutdown();
1951 // Safety: drops once, never accessed again
1952 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1953 }
1954}
1955
1956impl fidl::endpoints::Responder for AllocatorValidateBufferCollectionTokenResponder {
1957 type ControlHandle = AllocatorControlHandle;
1958
1959 fn control_handle(&self) -> &AllocatorControlHandle {
1960 &self.control_handle
1961 }
1962
1963 fn drop_without_shutdown(mut self) {
1964 // Safety: drops once, never accessed again due to mem::forget
1965 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1966 // Prevent Drop from running (which would shut down the channel)
1967 std::mem::forget(self);
1968 }
1969}
1970
1971impl AllocatorValidateBufferCollectionTokenResponder {
1972 /// Sends a response to the FIDL transaction.
1973 ///
1974 /// Sets the channel to shutdown if an error occurs.
1975 pub fn send(
1976 self,
1977 mut payload: &AllocatorValidateBufferCollectionTokenResponse,
1978 ) -> Result<(), fidl::Error> {
1979 let _result = self.send_raw(payload);
1980 if _result.is_err() {
1981 self.control_handle.shutdown();
1982 }
1983 self.drop_without_shutdown();
1984 _result
1985 }
1986
1987 /// Similar to "send" but does not shutdown the channel if an error occurs.
1988 pub fn send_no_shutdown_on_err(
1989 self,
1990 mut payload: &AllocatorValidateBufferCollectionTokenResponse,
1991 ) -> Result<(), fidl::Error> {
1992 let _result = self.send_raw(payload);
1993 self.drop_without_shutdown();
1994 _result
1995 }
1996
1997 fn send_raw(
1998 &self,
1999 mut payload: &AllocatorValidateBufferCollectionTokenResponse,
2000 ) -> Result<(), fidl::Error> {
2001 self.control_handle.inner.send::<fidl::encoding::FlexibleType<
2002 AllocatorValidateBufferCollectionTokenResponse,
2003 >>(
2004 fidl::encoding::Flexible::new(payload),
2005 self.tx_id,
2006 0x4c5ee91b02a7e68d,
2007 fidl::encoding::DynamicFlags::FLEXIBLE,
2008 )
2009 }
2010}
2011
2012#[must_use = "FIDL methods require a response to be sent"]
2013#[derive(Debug)]
2014pub struct AllocatorGetVmoInfoResponder {
2015 control_handle: std::mem::ManuallyDrop<AllocatorControlHandle>,
2016 tx_id: u32,
2017}
2018
2019/// Set the the channel to be shutdown (see [`AllocatorControlHandle::shutdown`])
2020/// if the responder is dropped without sending a response, so that the client
2021/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
2022impl std::ops::Drop for AllocatorGetVmoInfoResponder {
2023 fn drop(&mut self) {
2024 self.control_handle.shutdown();
2025 // Safety: drops once, never accessed again
2026 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
2027 }
2028}
2029
2030impl fidl::endpoints::Responder for AllocatorGetVmoInfoResponder {
2031 type ControlHandle = AllocatorControlHandle;
2032
2033 fn control_handle(&self) -> &AllocatorControlHandle {
2034 &self.control_handle
2035 }
2036
2037 fn drop_without_shutdown(mut self) {
2038 // Safety: drops once, never accessed again due to mem::forget
2039 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
2040 // Prevent Drop from running (which would shut down the channel)
2041 std::mem::forget(self);
2042 }
2043}
2044
2045impl AllocatorGetVmoInfoResponder {
2046 /// Sends a response to the FIDL transaction.
2047 ///
2048 /// Sets the channel to shutdown if an error occurs.
2049 pub fn send(
2050 self,
2051 mut result: Result<AllocatorGetVmoInfoResponse, Error>,
2052 ) -> Result<(), fidl::Error> {
2053 let _result = self.send_raw(result);
2054 if _result.is_err() {
2055 self.control_handle.shutdown();
2056 }
2057 self.drop_without_shutdown();
2058 _result
2059 }
2060
2061 /// Similar to "send" but does not shutdown the channel if an error occurs.
2062 pub fn send_no_shutdown_on_err(
2063 self,
2064 mut result: Result<AllocatorGetVmoInfoResponse, Error>,
2065 ) -> Result<(), fidl::Error> {
2066 let _result = self.send_raw(result);
2067 self.drop_without_shutdown();
2068 _result
2069 }
2070
2071 fn send_raw(
2072 &self,
2073 mut result: Result<AllocatorGetVmoInfoResponse, Error>,
2074 ) -> Result<(), fidl::Error> {
2075 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
2076 AllocatorGetVmoInfoResponse,
2077 Error,
2078 >>(
2079 fidl::encoding::FlexibleResult::new(result.as_mut().map_err(|e| *e)),
2080 self.tx_id,
2081 0x21a881120aa0ddf9,
2082 fidl::encoding::DynamicFlags::FLEXIBLE,
2083 )
2084 }
2085}
2086
2087#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
2088pub struct BufferCollectionMarker;
2089
2090impl fidl::endpoints::ProtocolMarker for BufferCollectionMarker {
2091 type Proxy = BufferCollectionProxy;
2092 type RequestStream = BufferCollectionRequestStream;
2093 #[cfg(target_os = "fuchsia")]
2094 type SynchronousProxy = BufferCollectionSynchronousProxy;
2095
2096 const DEBUG_NAME: &'static str = "(anonymous) BufferCollection";
2097}
2098pub type BufferCollectionWaitForAllBuffersAllocatedResult =
2099 Result<BufferCollectionWaitForAllBuffersAllocatedResponse, Error>;
2100pub type BufferCollectionCheckAllBuffersAllocatedResult = Result<(), Error>;
2101
2102pub trait BufferCollectionProxyInterface: Send + Sync {
2103 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
2104 fn r#sync(&self) -> Self::SyncResponseFut;
2105 fn r#release(&self) -> Result<(), fidl::Error>;
2106 fn r#set_name(&self, payload: &NodeSetNameRequest) -> Result<(), fidl::Error>;
2107 fn r#set_debug_client_info(
2108 &self,
2109 payload: &NodeSetDebugClientInfoRequest,
2110 ) -> Result<(), fidl::Error>;
2111 fn r#set_debug_timeout_log_deadline(
2112 &self,
2113 payload: &NodeSetDebugTimeoutLogDeadlineRequest,
2114 ) -> Result<(), fidl::Error>;
2115 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
2116 type GetNodeRefResponseFut: std::future::Future<Output = Result<NodeGetNodeRefResponse, fidl::Error>>
2117 + Send;
2118 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
2119 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
2120 + Send;
2121 fn r#is_alternate_for(
2122 &self,
2123 payload: NodeIsAlternateForRequest,
2124 ) -> Self::IsAlternateForResponseFut;
2125 type GetBufferCollectionIdResponseFut: std::future::Future<Output = Result<NodeGetBufferCollectionIdResponse, fidl::Error>>
2126 + Send;
2127 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut;
2128 fn r#set_weak(&self) -> Result<(), fidl::Error>;
2129 fn r#set_weak_ok(&self, payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error>;
2130 fn r#attach_node_tracking(
2131 &self,
2132 payload: NodeAttachNodeTrackingRequest,
2133 ) -> Result<(), fidl::Error>;
2134 fn r#set_constraints(
2135 &self,
2136 payload: BufferCollectionSetConstraintsRequest,
2137 ) -> Result<(), fidl::Error>;
2138 type WaitForAllBuffersAllocatedResponseFut: std::future::Future<
2139 Output = Result<BufferCollectionWaitForAllBuffersAllocatedResult, fidl::Error>,
2140 > + Send;
2141 fn r#wait_for_all_buffers_allocated(&self) -> Self::WaitForAllBuffersAllocatedResponseFut;
2142 type CheckAllBuffersAllocatedResponseFut: std::future::Future<
2143 Output = Result<BufferCollectionCheckAllBuffersAllocatedResult, fidl::Error>,
2144 > + Send;
2145 fn r#check_all_buffers_allocated(&self) -> Self::CheckAllBuffersAllocatedResponseFut;
2146 fn r#attach_token(
2147 &self,
2148 payload: BufferCollectionAttachTokenRequest,
2149 ) -> Result<(), fidl::Error>;
2150 fn r#attach_lifetime_tracking(
2151 &self,
2152 payload: BufferCollectionAttachLifetimeTrackingRequest,
2153 ) -> Result<(), fidl::Error>;
2154}
2155#[derive(Debug)]
2156#[cfg(target_os = "fuchsia")]
2157pub struct BufferCollectionSynchronousProxy {
2158 client: fidl::client::sync::Client,
2159}
2160
2161#[cfg(target_os = "fuchsia")]
2162impl fidl::endpoints::SynchronousProxy for BufferCollectionSynchronousProxy {
2163 type Proxy = BufferCollectionProxy;
2164 type Protocol = BufferCollectionMarker;
2165
2166 fn from_channel(inner: fidl::Channel) -> Self {
2167 Self::new(inner)
2168 }
2169
2170 fn into_channel(self) -> fidl::Channel {
2171 self.client.into_channel()
2172 }
2173
2174 fn as_channel(&self) -> &fidl::Channel {
2175 self.client.as_channel()
2176 }
2177}
2178
2179#[cfg(target_os = "fuchsia")]
2180impl BufferCollectionSynchronousProxy {
2181 pub fn new(channel: fidl::Channel) -> Self {
2182 Self { client: fidl::client::sync::Client::new(channel) }
2183 }
2184
2185 pub fn into_channel(self) -> fidl::Channel {
2186 self.client.into_channel()
2187 }
2188
2189 /// Waits until an event arrives and returns it. It is safe for other
2190 /// threads to make concurrent requests while waiting for an event.
2191 pub fn wait_for_event(
2192 &self,
2193 deadline: zx::MonotonicInstant,
2194 ) -> Result<BufferCollectionEvent, fidl::Error> {
2195 BufferCollectionEvent::decode(
2196 self.client.wait_for_event::<BufferCollectionMarker>(deadline)?,
2197 )
2198 }
2199
2200 /// Ensure that previous messages have been received server side. This is
2201 /// particularly useful after previous messages that created new tokens,
2202 /// because a token must be known to the sysmem server before sending the
2203 /// token to another participant.
2204 ///
2205 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
2206 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
2207 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
2208 /// to mitigate the possibility of a hostile/fake
2209 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
2210 /// Another way is to pass the token to
2211 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
2212 /// the token as part of exchanging it for a
2213 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
2214 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
2215 /// of stalling.
2216 ///
2217 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
2218 /// and then starting and completing a `Sync`, it's then safe to send the
2219 /// `BufferCollectionToken` client ends to other participants knowing the
2220 /// server will recognize the tokens when they're sent by the other
2221 /// participants to sysmem in a
2222 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
2223 /// efficient way to create tokens while avoiding unnecessary round trips.
2224 ///
2225 /// Other options include waiting for each
2226 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
2227 /// individually (using separate call to `Sync` after each), or calling
2228 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
2229 /// converted to a `BufferCollection` via
2230 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
2231 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
2232 /// the sync step and can create multiple tokens at once.
2233 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
2234 let _response = self.client.send_query::<
2235 fidl::encoding::EmptyPayload,
2236 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
2237 BufferCollectionMarker,
2238 >(
2239 (),
2240 0x11ac2555cf575b54,
2241 fidl::encoding::DynamicFlags::FLEXIBLE,
2242 ___deadline,
2243 )?
2244 .into_result::<BufferCollectionMarker>("sync")?;
2245 Ok(_response)
2246 }
2247
2248 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
2249 ///
2250 /// Normally a participant will convert a `BufferCollectionToken` into a
2251 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
2252 /// `Release` via the token (and then close the channel immediately or
2253 /// shortly later in response to server closing the server end), which
2254 /// avoids causing buffer collection failure. Without a prior `Release`,
2255 /// closing the `BufferCollectionToken` client end will cause buffer
2256 /// collection failure.
2257 ///
2258 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
2259 ///
2260 /// By default the server handles unexpected closure of a
2261 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
2262 /// first) by failing the buffer collection. Partly this is to expedite
2263 /// closing VMO handles to reclaim memory when any participant fails. If a
2264 /// participant would like to cleanly close a `BufferCollection` without
2265 /// causing buffer collection failure, the participant can send `Release`
2266 /// before closing the `BufferCollection` client end. The `Release` can
2267 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
2268 /// buffer collection won't require constraints from this node in order to
2269 /// allocate. If after `SetConstraints`, the constraints are retained and
2270 /// aggregated, despite the lack of `BufferCollection` connection at the
2271 /// time of constraints aggregation.
2272 ///
2273 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
2274 ///
2275 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
2276 /// end (without `Release` first) will trigger failure of the buffer
2277 /// collection. To close a `BufferCollectionTokenGroup` channel without
2278 /// failing the buffer collection, ensure that AllChildrenPresent() has been
2279 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
2280 /// client end.
2281 ///
2282 /// If `Release` occurs before
2283 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
2284 /// buffer collection will fail (triggered by reception of `Release` without
2285 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
2286 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
2287 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
2288 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
2289 /// close requires `AllChildrenPresent` (if not already sent), then
2290 /// `Release`, then close client end.
2291 ///
2292 /// If `Release` occurs after `AllChildrenPresent`, the children and all
2293 /// their constraints remain intact (just as they would if the
2294 /// `BufferCollectionTokenGroup` channel had remained open), and the client
2295 /// end close doesn't trigger buffer collection failure.
2296 ///
2297 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
2298 ///
2299 /// For brevity, the per-channel-protocol paragraphs above ignore the
2300 /// separate failure domain created by
2301 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
2302 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
2303 /// unexpectedly closes (without `Release` first) and that client end is
2304 /// under a failure domain, instead of failing the whole buffer collection,
2305 /// the failure domain is failed, but the buffer collection itself is
2306 /// isolated from failure of the failure domain. Such failure domains can be
2307 /// nested, in which case only the inner-most failure domain in which the
2308 /// `Node` resides fails.
2309 pub fn r#release(&self) -> Result<(), fidl::Error> {
2310 self.client.send::<fidl::encoding::EmptyPayload>(
2311 (),
2312 0x6a5cae7d6d6e04c6,
2313 fidl::encoding::DynamicFlags::FLEXIBLE,
2314 )
2315 }
2316
2317 /// Set a name for VMOs in this buffer collection.
2318 ///
2319 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
2320 /// will be truncated to fit. The name of the vmo will be suffixed with the
2321 /// buffer index within the collection (if the suffix fits within
2322 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
2323 /// listed in the inspect data.
2324 ///
2325 /// The name only affects VMOs allocated after the name is set; this call
2326 /// does not rename existing VMOs. If multiple clients set different names
2327 /// then the larger priority value will win. Setting a new name with the
2328 /// same priority as a prior name doesn't change the name.
2329 ///
2330 /// All table fields are currently required.
2331 ///
2332 /// + request `priority` The name is only set if this is the first `SetName`
2333 /// or if `priority` is greater than any previous `priority` value in
2334 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
2335 /// + request `name` The name for VMOs created under this buffer collection.
2336 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
2337 self.client.send::<NodeSetNameRequest>(
2338 payload,
2339 0xb41f1624f48c1e9,
2340 fidl::encoding::DynamicFlags::FLEXIBLE,
2341 )
2342 }
2343
2344 /// Set information about the current client that can be used by sysmem to
2345 /// help diagnose leaking memory and allocation stalls waiting for a
2346 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
2347 ///
2348 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
2349 /// `Node`(s) derived from this `Node`, unless overriden by
2350 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
2351 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
2352 ///
2353 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
2354 /// `Allocator` is the most efficient way to ensure that all
2355 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
2356 /// set, and is also more efficient than separately sending the same debug
2357 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
2358 /// created [`fuchsia.sysmem2/Node`].
2359 ///
2360 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
2361 /// indicate which client is closing their channel first, leading to subtree
2362 /// failure (which can be normal if the purpose of the subtree is over, but
2363 /// if happening earlier than expected, the client-channel-specific name can
2364 /// help diagnose where the failure is first coming from, from sysmem's
2365 /// point of view).
2366 ///
2367 /// All table fields are currently required.
2368 ///
2369 /// + request `name` This can be an arbitrary string, but the current
2370 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
2371 /// + request `id` This can be an arbitrary id, but the current process ID
2372 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
2373 pub fn r#set_debug_client_info(
2374 &self,
2375 mut payload: &NodeSetDebugClientInfoRequest,
2376 ) -> Result<(), fidl::Error> {
2377 self.client.send::<NodeSetDebugClientInfoRequest>(
2378 payload,
2379 0x5cde8914608d99b1,
2380 fidl::encoding::DynamicFlags::FLEXIBLE,
2381 )
2382 }
2383
2384 /// Sysmem logs a warning if sysmem hasn't seen
2385 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
2386 /// within 5 seconds after creation of a new collection.
2387 ///
2388 /// Clients can call this method to change when the log is printed. If
2389 /// multiple client set the deadline, it's unspecified which deadline will
2390 /// take effect.
2391 ///
2392 /// In most cases the default works well.
2393 ///
2394 /// All table fields are currently required.
2395 ///
2396 /// + request `deadline` The time at which sysmem will start trying to log
2397 /// the warning, unless all constraints are with sysmem by then.
2398 pub fn r#set_debug_timeout_log_deadline(
2399 &self,
2400 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
2401 ) -> Result<(), fidl::Error> {
2402 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
2403 payload,
2404 0x716b0af13d5c0806,
2405 fidl::encoding::DynamicFlags::FLEXIBLE,
2406 )
2407 }
2408
2409 /// This enables verbose logging for the buffer collection.
2410 ///
2411 /// Verbose logging includes constraints set via
2412 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
2413 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
2414 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
2415 /// the tree of `Node`(s).
2416 ///
2417 /// Normally sysmem prints only a single line complaint when aggregation
2418 /// fails, with just the specific detailed reason that aggregation failed,
2419 /// with little surrounding context. While this is often enough to diagnose
2420 /// a problem if only a small change was made and everything was working
2421 /// before the small change, it's often not particularly helpful for getting
2422 /// a new buffer collection to work for the first time. Especially with
2423 /// more complex trees of nodes, involving things like
2424 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
2425 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
2426 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
2427 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
2428 /// looks like and why it's failing a logical allocation, or why a tree or
2429 /// subtree is failing sooner than expected.
2430 ///
2431 /// The intent of the extra logging is to be acceptable from a performance
2432 /// point of view, under the assumption that verbose logging is only enabled
2433 /// on a low number of buffer collections. If we're not tracking down a bug,
2434 /// we shouldn't send this message.
2435 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
2436 self.client.send::<fidl::encoding::EmptyPayload>(
2437 (),
2438 0x5209c77415b4dfad,
2439 fidl::encoding::DynamicFlags::FLEXIBLE,
2440 )
2441 }
2442
2443 /// This gets a handle that can be used as a parameter to
2444 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
2445 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
2446 /// client obtained this handle from this `Node`.
2447 ///
2448 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
2449 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
2450 /// despite the two calls typically being on different channels.
2451 ///
2452 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
2453 ///
2454 /// All table fields are currently required.
2455 ///
2456 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
2457 /// different `Node` channel, to prove that the client obtained the handle
2458 /// from this `Node`.
2459 pub fn r#get_node_ref(
2460 &self,
2461 ___deadline: zx::MonotonicInstant,
2462 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
2463 let _response = self.client.send_query::<
2464 fidl::encoding::EmptyPayload,
2465 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
2466 BufferCollectionMarker,
2467 >(
2468 (),
2469 0x5b3d0e51614df053,
2470 fidl::encoding::DynamicFlags::FLEXIBLE,
2471 ___deadline,
2472 )?
2473 .into_result::<BufferCollectionMarker>("get_node_ref")?;
2474 Ok(_response)
2475 }
2476
2477 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
2478 /// rooted at a different child token of a common parent
2479 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
2480 /// passed-in `node_ref`.
2481 ///
2482 /// This call is for assisting with admission control de-duplication, and
2483 /// with debugging.
2484 ///
2485 /// The `node_ref` must be obtained using
2486 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
2487 ///
2488 /// The `node_ref` can be a duplicated handle; it's not necessary to call
2489 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
2490 ///
2491 /// If a calling token may not actually be a valid token at all due to a
2492 /// potentially hostile/untrusted provider of the token, call
2493 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
2494 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
2495 /// never responds due to a calling token not being a real token (not really
2496 /// talking to sysmem). Another option is to call
2497 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
2498 /// which also validates the token along with converting it to a
2499 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
2500 ///
2501 /// All table fields are currently required.
2502 ///
2503 /// - response `is_alternate`
2504 /// - true: The first parent node in common between the calling node and
2505 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
2506 /// that the calling `Node` and the `node_ref` `Node` will not have both
2507 /// their constraints apply - rather sysmem will choose one or the other
2508 /// of the constraints - never both. This is because only one child of
2509 /// a `BufferCollectionTokenGroup` is selected during logical
2510 /// allocation, with only that one child's subtree contributing to
2511 /// constraints aggregation.
2512 /// - false: The first parent node in common between the calling `Node`
2513 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
2514 /// Currently, this means the first parent node in common is a
2515 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
2516 /// `Release`ed). This means that the calling `Node` and the `node_ref`
2517 /// `Node` may have both their constraints apply during constraints
2518 /// aggregation of the logical allocation, if both `Node`(s) are
2519 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
2520 /// this case, there is no `BufferCollectionTokenGroup` that will
2521 /// directly prevent the two `Node`(s) from both being selected and
2522 /// their constraints both aggregated, but even when false, one or both
2523 /// `Node`(s) may still be eliminated from consideration if one or both
2524 /// `Node`(s) has a direct or indirect parent
2525 /// `BufferCollectionTokenGroup` which selects a child subtree other
2526 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
2527 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
2528 /// associated with the same buffer collection as the calling `Node`.
2529 /// Another reason for this error is if the `node_ref` is an
2530 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
2531 /// a real `node_ref` obtained from `GetNodeRef`.
2532 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
2533 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
2534 /// the needed rights expected on a real `node_ref`.
2535 /// * No other failing status codes are returned by this call. However,
2536 /// sysmem may add additional codes in future, so the client should have
2537 /// sensible default handling for any failing status code.
2538 pub fn r#is_alternate_for(
2539 &self,
2540 mut payload: NodeIsAlternateForRequest,
2541 ___deadline: zx::MonotonicInstant,
2542 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
2543 let _response = self.client.send_query::<
2544 NodeIsAlternateForRequest,
2545 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
2546 BufferCollectionMarker,
2547 >(
2548 &mut payload,
2549 0x3a58e00157e0825,
2550 fidl::encoding::DynamicFlags::FLEXIBLE,
2551 ___deadline,
2552 )?
2553 .into_result::<BufferCollectionMarker>("is_alternate_for")?;
2554 Ok(_response.map(|x| x))
2555 }
2556
2557 /// Get the buffer collection ID. This ID is also available from
2558 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
2559 /// within the collection).
2560 ///
2561 /// This call is mainly useful in situations where we can't convey a
2562 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
2563 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
2564 /// handle, which can be joined back up with a `BufferCollection` client end
2565 /// that was created via a different path. Prefer to convey a
2566 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
2567 ///
2568 /// Trusting a `buffer_collection_id` value from a source other than sysmem
2569 /// is analogous to trusting a koid value from a source other than zircon.
2570 /// Both should be avoided unless really necessary, and both require
2571 /// caution. In some situations it may be reasonable to refer to a
2572 /// pre-established `BufferCollection` by `buffer_collection_id` via a
2573 /// protocol for efficiency reasons, but an incoming value purporting to be
2574 /// a `buffer_collection_id` is not sufficient alone to justify granting the
2575 /// sender of the `buffer_collection_id` any capability. The sender must
2576 /// first prove to a receiver that the sender has/had a VMO or has/had a
2577 /// `BufferCollectionToken` to the same collection by sending a handle that
2578 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
2579 /// `buffer_collection_id` value. The receiver should take care to avoid
2580 /// assuming that a sender had a `BufferCollectionToken` in cases where the
2581 /// sender has only proven that the sender had a VMO.
2582 ///
2583 /// - response `buffer_collection_id` This ID is unique per buffer
2584 /// collection per boot. Each buffer is uniquely identified by the
2585 /// `buffer_collection_id` and `buffer_index` together.
2586 pub fn r#get_buffer_collection_id(
2587 &self,
2588 ___deadline: zx::MonotonicInstant,
2589 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
2590 let _response = self.client.send_query::<
2591 fidl::encoding::EmptyPayload,
2592 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
2593 BufferCollectionMarker,
2594 >(
2595 (),
2596 0x77d19a494b78ba8c,
2597 fidl::encoding::DynamicFlags::FLEXIBLE,
2598 ___deadline,
2599 )?
2600 .into_result::<BufferCollectionMarker>("get_buffer_collection_id")?;
2601 Ok(_response)
2602 }
2603
2604 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
2605 /// created after this message to weak, which means that a client's `Node`
2606 /// client end (or a child created after this message) is not alone
2607 /// sufficient to keep allocated VMOs alive.
2608 ///
2609 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
2610 /// `close_weak_asap`.
2611 ///
2612 /// This message is only permitted before the `Node` becomes ready for
2613 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
2614 /// * `BufferCollectionToken`: any time
2615 /// * `BufferCollection`: before `SetConstraints`
2616 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
2617 ///
2618 /// Currently, no conversion from strong `Node` to weak `Node` after ready
2619 /// for allocation is provided, but a client can simulate that by creating
2620 /// an additional `Node` before allocation and setting that additional
2621 /// `Node` to weak, and then potentially at some point later sending
2622 /// `Release` and closing the client end of the client's strong `Node`, but
2623 /// keeping the client's weak `Node`.
2624 ///
2625 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
2626 /// collection failure (all `Node` client end(s) will see
2627 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
2628 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
2629 /// this situation until all `Node`(s) are ready for allocation. For initial
2630 /// allocation to succeed, at least one strong `Node` is required to exist
2631 /// at allocation time, but after that client receives VMO handles, that
2632 /// client can `BufferCollection.Release` and close the client end without
2633 /// causing this type of failure.
2634 ///
2635 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
2636 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
2637 /// separately as appropriate.
2638 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
2639 self.client.send::<fidl::encoding::EmptyPayload>(
2640 (),
2641 0x22dd3ea514eeffe1,
2642 fidl::encoding::DynamicFlags::FLEXIBLE,
2643 )
2644 }
2645
2646 /// This indicates to sysmem that the client is prepared to pay attention to
2647 /// `close_weak_asap`.
2648 ///
2649 /// If sent, this message must be before
2650 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
2651 ///
2652 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
2653 /// send this message before `WaitForAllBuffersAllocated`, or a parent
2654 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
2655 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
2656 /// trigger buffer collection failure.
2657 ///
2658 /// This message is necessary because weak sysmem VMOs have not always been
2659 /// a thing, so older clients are not aware of the need to pay attention to
2660 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
2661 /// sysmem weak VMO handles asap. By having this message and requiring
2662 /// participants to indicate their acceptance of this aspect of the overall
2663 /// protocol, we avoid situations where an older client is delivered a weak
2664 /// VMO without any way for sysmem to get that VMO to close quickly later
2665 /// (and on a per-buffer basis).
2666 ///
2667 /// A participant that doesn't handle `close_weak_asap` and also doesn't
2668 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
2669 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
2670 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
2671 /// same participant has a child/delegate which does retrieve VMOs, that
2672 /// child/delegate will need to send `SetWeakOk` before
2673 /// `WaitForAllBuffersAllocated`.
2674 ///
2675 /// + request `for_child_nodes_also` If present and true, this means direct
2676 /// child nodes of this node created after this message plus all
2677 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
2678 /// those nodes. Any child node of this node that was created before this
2679 /// message is not included. This setting is "sticky" in the sense that a
2680 /// subsequent `SetWeakOk` without this bool set to true does not reset
2681 /// the server-side bool. If this creates a problem for a participant, a
2682 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
2683 /// tokens instead, as appropriate. A participant should only set
2684 /// `for_child_nodes_also` true if the participant can really promise to
2685 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
2686 /// weak VMO handles held by participants holding the corresponding child
2687 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
2688 /// which are using sysmem(1) can be weak, despite the clients of those
2689 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
2690 /// direct way to find out about `close_weak_asap`. This only applies to
2691 /// descendents of this `Node` which are using sysmem(1), not to this
2692 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
2693 /// token, which will fail allocation unless an ancestor of this `Node`
2694 /// specified `for_child_nodes_also` true.
2695 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
2696 self.client.send::<NodeSetWeakOkRequest>(
2697 &mut payload,
2698 0x38a44fc4d7724be9,
2699 fidl::encoding::DynamicFlags::FLEXIBLE,
2700 )
2701 }
2702
2703 /// The server_end will be closed after this `Node` and any child nodes have
2704 /// have released their buffer counts, making those counts available for
2705 /// reservation by a different `Node` via
2706 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
2707 ///
2708 /// The `Node` buffer counts may not be released until the entire tree of
2709 /// `Node`(s) is closed or failed, because
2710 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
2711 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
2712 /// `Node` buffer counts remain reserved until the orphaned node is later
2713 /// cleaned up.
2714 ///
2715 /// If the `Node` exceeds a fairly large number of attached eventpair server
2716 /// ends, a log message will indicate this and the `Node` (and the
2717 /// appropriate) sub-tree will fail.
2718 ///
2719 /// The `server_end` will remain open when
2720 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
2721 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
2722 /// [`fuchsia.sysmem2/BufferCollection`].
2723 ///
2724 /// This message can also be used with a
2725 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
2726 pub fn r#attach_node_tracking(
2727 &self,
2728 mut payload: NodeAttachNodeTrackingRequest,
2729 ) -> Result<(), fidl::Error> {
2730 self.client.send::<NodeAttachNodeTrackingRequest>(
2731 &mut payload,
2732 0x3f22f2a293d3cdac,
2733 fidl::encoding::DynamicFlags::FLEXIBLE,
2734 )
2735 }
2736
2737 /// Provide [`fuchsia.sysmem2/BufferCollectionConstraints`] to the buffer
2738 /// collection.
2739 ///
2740 /// A participant may only call
2741 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] up to once per
2742 /// [`fuchsia.sysmem2/BufferCollection`].
2743 ///
2744 /// For buffer allocation to be attempted, all holders of a
2745 /// `BufferCollection` client end need to call `SetConstraints` before
2746 /// sysmem will attempt to allocate buffers.
2747 pub fn r#set_constraints(
2748 &self,
2749 mut payload: BufferCollectionSetConstraintsRequest,
2750 ) -> Result<(), fidl::Error> {
2751 self.client.send::<BufferCollectionSetConstraintsRequest>(
2752 &mut payload,
2753 0x1fde0f19d650197b,
2754 fidl::encoding::DynamicFlags::FLEXIBLE,
2755 )
2756 }
2757
2758 /// Wait until all buffers are allocated.
2759 ///
2760 /// This FIDL call completes when buffers have been allocated, or completes
2761 /// with some failure detail if allocation has been attempted but failed.
2762 ///
2763 /// The following must occur before buffers will be allocated:
2764 /// * All [`fuchsia.sysmem2/BufferCollectionToken`](s) of the buffer
2765 /// collection must be turned in via `BindSharedCollection` to get a
2766 /// [`fuchsia.sysmem2/BufferCollection`] (for brevity, this is assuming
2767 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`] isn't being used),
2768 /// or have had [`fuchsia.sysmem2/BufferCollectionToken.Release`] sent
2769 /// to them.
2770 /// * All [`fuchsia.sysmem2/BufferCollection`](s) of the buffer collection
2771 /// must have had [`fuchsia.sysmem2/BufferCollection.SetConstraints`]
2772 /// sent to them, or had [`fuchsia.sysmem2/BufferCollection.Release`]
2773 /// sent to them.
2774 ///
2775 /// - result `buffer_collection_info` The VMO handles and other related
2776 /// info.
2777 /// * error `[fuchsia.sysmem2/Error.NO_MEMORY]` The request is valid but
2778 /// cannot be fulfilled due to resource exhaustion.
2779 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION`] The request is
2780 /// malformed.
2781 /// * error `[fuchsia.sysmem2/Error.CONSTRAINTS_INTERSECTION_EMPTY`] The
2782 /// request is valid but cannot be satisfied, perhaps due to hardware
2783 /// limitations. This can happen if participants have incompatible
2784 /// constraints (empty intersection, roughly speaking). See the log for
2785 /// more info. In cases where a participant could potentially be treated
2786 /// as optional, see [`BufferCollectionTokenGroup`]. When using
2787 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], this will be the
2788 /// error code if there aren't enough buffers in the pre-existing
2789 /// collection to satisfy the constraints set on the attached token and
2790 /// any sub-tree of tokens derived from the attached token.
2791 pub fn r#wait_for_all_buffers_allocated(
2792 &self,
2793 ___deadline: zx::MonotonicInstant,
2794 ) -> Result<BufferCollectionWaitForAllBuffersAllocatedResult, fidl::Error> {
2795 let _response = self
2796 .client
2797 .send_query::<fidl::encoding::EmptyPayload, fidl::encoding::FlexibleResultType<
2798 BufferCollectionWaitForAllBuffersAllocatedResponse,
2799 Error,
2800 >, BufferCollectionMarker>(
2801 (),
2802 0x62300344b61404e,
2803 fidl::encoding::DynamicFlags::FLEXIBLE,
2804 ___deadline,
2805 )?
2806 .into_result::<BufferCollectionMarker>("wait_for_all_buffers_allocated")?;
2807 Ok(_response.map(|x| x))
2808 }
2809
2810 /// Checks whether all the buffers have been allocated, in a polling
2811 /// fashion.
2812 ///
2813 /// * If the buffer collection has been allocated, returns success.
2814 /// * If the buffer collection failed allocation, returns the same
2815 /// [`fuchsia.sysmem2/Error`] as
2816 /// [`fuchsia.sysmem2/BufferCollection/WaitForAllBuffersAllocated`] would
2817 /// return.
2818 /// * error [`fuchsia.sysmem2/Error.PENDING`] The buffer collection hasn't
2819 /// attempted allocation yet. This means that WaitForAllBuffersAllocated
2820 /// would not respond quickly.
2821 pub fn r#check_all_buffers_allocated(
2822 &self,
2823 ___deadline: zx::MonotonicInstant,
2824 ) -> Result<BufferCollectionCheckAllBuffersAllocatedResult, fidl::Error> {
2825 let _response = self.client.send_query::<
2826 fidl::encoding::EmptyPayload,
2827 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
2828 BufferCollectionMarker,
2829 >(
2830 (),
2831 0x35a5fe77ce939c10,
2832 fidl::encoding::DynamicFlags::FLEXIBLE,
2833 ___deadline,
2834 )?
2835 .into_result::<BufferCollectionMarker>("check_all_buffers_allocated")?;
2836 Ok(_response.map(|x| x))
2837 }
2838
2839 /// Create a new token to add a new participant to an existing logical
2840 /// buffer collection, if the existing collection's buffer counts,
2841 /// constraints, and participants allow.
2842 ///
2843 /// This can be useful in replacing a failed participant, and/or in
2844 /// adding/re-adding a participant after buffers have already been
2845 /// allocated.
2846 ///
2847 /// When [`fuchsia.sysmem2/BufferCollection.AttachToken`] is used, the sub
2848 /// tree rooted at the attached [`fuchsia.sysmem2/BufferCollectionToken`]
2849 /// goes through the normal procedure of setting constraints or closing
2850 /// [`fuchsia.sysmem2/Node`](s), and then appearing to allocate buffers from
2851 /// clients' point of view, despite the possibility that all the buffers
2852 /// were actually allocated previously. This process is called "logical
2853 /// allocation". Most instances of "allocation" in docs for other messages
2854 /// can also be read as "allocation or logical allocation" while remaining
2855 /// valid, but we just say "allocation" in most places for brevity/clarity
2856 /// of explanation, with the details of "logical allocation" left for the
2857 /// docs here on `AttachToken`.
2858 ///
2859 /// Failure of an attached `Node` does not propagate to the parent of the
2860 /// attached `Node`. More generally, failure of a child `Node` is blocked
2861 /// from reaching its parent `Node` if the child is attached, or if the
2862 /// child is dispensable and the failure occurred after logical allocation
2863 /// (see [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`]).
2864 ///
2865 /// A participant may in some scenarios choose to initially use a
2866 /// dispensable token for a given instance of a delegate participant, and
2867 /// then later if the first instance of that delegate participant fails, a
2868 /// new second instance of that delegate participant my be given a token
2869 /// created with `AttachToken`.
2870 ///
2871 /// From the point of view of the [`fuchsia.sysmem2/BufferCollectionToken`]
2872 /// client end, the token acts like any other token. The client can
2873 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] the token as needed,
2874 /// and can send the token to a different process/participant. The
2875 /// `BufferCollectionToken` `Node` should be converted to a
2876 /// `BufferCollection` `Node` as normal by sending
2877 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or can be closed
2878 /// without causing subtree failure by sending
2879 /// [`fuchsia.sysmem2/BufferCollectionToken.Release`]. Assuming the former,
2880 /// the [`fuchsia.sysmem2/BufferCollection.SetConstraints`] message or
2881 /// [`fuchsia.sysmem2/BufferCollection.Release`] message should be sent to
2882 /// the `BufferCollection`.
2883 ///
2884 /// Within the subtree, a success result from
2885 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`] means
2886 /// the subtree participants' constraints were satisfiable using the
2887 /// already-existing buffer collection, the already-established
2888 /// [`fuchsia.sysmem2/BufferCollectionInfo`] including image format
2889 /// constraints, and the already-existing other participants (already added
2890 /// via successful logical allocation) and their specified buffer counts in
2891 /// their constraints. A failure result means the new participants'
2892 /// constraints cannot be satisfied using the existing buffer collection and
2893 /// its already-added participants. Creating a new collection instead may
2894 /// allow all participants' constraints to be satisfied, assuming
2895 /// `SetDispensable` is used in place of `AttachToken`, or a normal token is
2896 /// used.
2897 ///
2898 /// A token created with `AttachToken` performs constraints aggregation with
2899 /// all constraints currently in effect on the buffer collection, plus the
2900 /// attached token under consideration plus child tokens under the attached
2901 /// token which are not themselves an attached token or under such a token.
2902 /// Further subtrees under this subtree are considered for logical
2903 /// allocation only after this subtree has completed logical allocation.
2904 ///
2905 /// Assignment of existing buffers to participants'
2906 /// [`fuchsia.sysmem2/BufferCollectionConstraints.min_buffer_count_for_camping`]
2907 /// etc is first-come first-served, but a child can't logically allocate
2908 /// before all its parents have sent `SetConstraints`.
2909 ///
2910 /// See also [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`], which
2911 /// in contrast to `AttachToken`, has the created token `Node` + child
2912 /// `Node`(s) (in the created subtree but not in any subtree under this
2913 /// subtree) participate in constraints aggregation along with its parent
2914 /// during the parent's allocation or logical allocation.
2915 ///
2916 /// Similar to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], the
2917 /// newly created token needs to be [`fuchsia.sysmem2/Node.Sync`]ed to
2918 /// sysmem before the new token can be passed to `BindSharedCollection`. The
2919 /// `Sync` of the new token can be accomplished with
2920 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after converting the created
2921 /// `BufferCollectionToken` to a `BufferCollection`. Alternately,
2922 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on the new token also
2923 /// works. Or using [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`]
2924 /// works. As usual, a `BufferCollectionToken.Sync` can be started after any
2925 /// `BufferCollectionToken.Duplicate` messages have been sent via the newly
2926 /// created token, to also sync those additional tokens to sysmem using a
2927 /// single round-trip.
2928 ///
2929 /// All table fields are currently required.
2930 ///
2931 /// + request `rights_attentuation_mask` This allows attenuating the VMO
2932 /// rights of the subtree. These values for `rights_attenuation_mask`
2933 /// result in no attenuation (note that 0 is not on this list):
2934 /// + ZX_RIGHT_SAME_RIGHTS (preferred)
2935 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
2936 /// + request `token_request` The server end of the `BufferCollectionToken`
2937 /// channel. The client retains the client end.
2938 pub fn r#attach_token(
2939 &self,
2940 mut payload: BufferCollectionAttachTokenRequest,
2941 ) -> Result<(), fidl::Error> {
2942 self.client.send::<BufferCollectionAttachTokenRequest>(
2943 &mut payload,
2944 0x46ac7d0008492982,
2945 fidl::encoding::DynamicFlags::FLEXIBLE,
2946 )
2947 }
2948
2949 /// Set up an eventpair to be signalled (`ZX_EVENTPAIR_PEER_CLOSED`) when
2950 /// buffers have been allocated and only the specified number of buffers (or
2951 /// fewer) remain in the buffer collection.
2952 ///
2953 /// [`fuchsia.sysmem2/BufferCollection.AttachLifetimeTracking`] allows a
2954 /// client to wait until an old buffer collection is fully or mostly
2955 /// deallocated before attempting allocation of a new buffer collection. The
2956 /// eventpair is only signalled when the buffers of this collection have
2957 /// been fully deallocated (not just un-referenced by clients, but all the
2958 /// memory consumed by those buffers has been fully reclaimed/recycled), or
2959 /// when allocation or logical allocation fails for the tree or subtree
2960 /// including this [`fuchsia.sysmem2/BufferCollection`].
2961 ///
2962 /// The eventpair won't be signalled until allocation or logical allocation
2963 /// has completed; until then, the collection's current buffer count is
2964 /// ignored.
2965 ///
2966 /// If logical allocation fails for an attached subtree (using
2967 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]), the server end of the
2968 /// eventpair will close during that failure regardless of the number of
2969 /// buffers potenitally allocated in the overall buffer collection. This is
2970 /// for logical allocation consistency with normal allocation.
2971 ///
2972 /// The lifetime signalled by this event includes asynchronous cleanup of
2973 /// allocated buffers, and this asynchronous cleanup cannot occur until all
2974 /// holders of VMO handles to the buffers have closed those VMO handles.
2975 /// Therefore, clients should take care not to become blocked forever
2976 /// waiting for `ZX_EVENTPAIR_PEER_CLOSED` to be signalled if any of the
2977 /// participants using the logical buffer collection (including the waiter
2978 /// itself) are less trusted, less reliable, or potentially blocked by the
2979 /// wait itself. Waiting asynchronously is recommended. Setting a deadline
2980 /// for the client wait may be prudent, depending on details of how the
2981 /// collection and/or its VMOs are used or shared. Failure to allocate a
2982 /// new/replacement buffer collection is better than getting stuck forever.
2983 ///
2984 /// The sysmem server itself intentionally does not perform any waiting on
2985 /// already-failed collections' VMOs to finish cleaning up before attempting
2986 /// a new allocation, and the sysmem server intentionally doesn't retry
2987 /// allocation if a new allocation fails due to out of memory, even if that
2988 /// failure is potentially due to continued existence of an old collection's
2989 /// VMOs. This `AttachLifetimeTracking` message is how an initiator can
2990 /// mitigate too much overlap of old VMO lifetimes with new VMO lifetimes,
2991 /// as long as the waiting client is careful to not create a deadlock.
2992 ///
2993 /// Continued existence of old collections that are still cleaning up is not
2994 /// the only reason that a new allocation may fail due to insufficient
2995 /// memory, even if the new allocation is allocating physically contiguous
2996 /// buffers. Overall system memory pressure can also be the cause of failure
2997 /// to allocate a new collection. See also
2998 /// [`fuchsia.memorypressure/Provider`].
2999 ///
3000 /// `AttachLifetimeTracking` is meant to be compatible with other protocols
3001 /// with a similar `AttachLifetimeTracking` message; duplicates of the same
3002 /// `eventpair` handle (server end) can be sent via more than one
3003 /// `AttachLifetimeTracking` message to different protocols, and the
3004 /// `ZX_EVENTPAIR_PEER_CLOSED` will be signalled for the client end when all
3005 /// the conditions are met (all holders of duplicates have closed their
3006 /// server end handle(s)). Also, thanks to how eventpair endponts work, the
3007 /// client end can (also) be duplicated without preventing the
3008 /// `ZX_EVENTPAIR_PEER_CLOSED` signal.
3009 ///
3010 /// The server intentionally doesn't "trust" any signals set on the
3011 /// `server_end`. This mechanism intentionally uses only
3012 /// `ZX_EVENTPAIR_PEER_CLOSED` set on the client end, which can't be set
3013 /// "early", and is only set when all handles to the server end eventpair
3014 /// are closed. No meaning is associated with any of the other signals, and
3015 /// clients should ignore any other signal bits on either end of the
3016 /// `eventpair`.
3017 ///
3018 /// The `server_end` may lack `ZX_RIGHT_SIGNAL` or `ZX_RIGHT_SIGNAL_PEER`,
3019 /// but must have `ZX_RIGHT_DUPLICATE` (and must have `ZX_RIGHT_TRANSFER` to
3020 /// transfer without causing `BufferCollection` channel failure).
3021 ///
3022 /// All table fields are currently required.
3023 ///
3024 /// + request `server_end` This eventpair handle will be closed by the
3025 /// sysmem server when buffers have been allocated initially and the
3026 /// number of buffers is then less than or equal to `buffers_remaining`.
3027 /// + request `buffers_remaining` Wait for all but `buffers_remaining` (or
3028 /// fewer) buffers to be fully deallocated. A number greater than zero can
3029 /// be useful in situations where a known number of buffers are
3030 /// intentionally not closed so that the data can continue to be used,
3031 /// such as for keeping the last available video frame displayed in the UI
3032 /// even if the video stream was using protected output buffers. It's
3033 /// outside the scope of the `BufferCollection` interface (at least for
3034 /// now) to determine how many buffers may be held without closing, but
3035 /// it'll typically be in the range 0-2.
3036 pub fn r#attach_lifetime_tracking(
3037 &self,
3038 mut payload: BufferCollectionAttachLifetimeTrackingRequest,
3039 ) -> Result<(), fidl::Error> {
3040 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
3041 &mut payload,
3042 0x3ecb510113116dcf,
3043 fidl::encoding::DynamicFlags::FLEXIBLE,
3044 )
3045 }
3046}
3047
3048#[cfg(target_os = "fuchsia")]
3049impl From<BufferCollectionSynchronousProxy> for zx::NullableHandle {
3050 fn from(value: BufferCollectionSynchronousProxy) -> Self {
3051 value.into_channel().into()
3052 }
3053}
3054
3055#[cfg(target_os = "fuchsia")]
3056impl From<fidl::Channel> for BufferCollectionSynchronousProxy {
3057 fn from(value: fidl::Channel) -> Self {
3058 Self::new(value)
3059 }
3060}
3061
3062#[cfg(target_os = "fuchsia")]
3063impl fidl::endpoints::FromClient for BufferCollectionSynchronousProxy {
3064 type Protocol = BufferCollectionMarker;
3065
3066 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionMarker>) -> Self {
3067 Self::new(value.into_channel())
3068 }
3069}
3070
3071#[derive(Debug, Clone)]
3072pub struct BufferCollectionProxy {
3073 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
3074}
3075
3076impl fidl::endpoints::Proxy for BufferCollectionProxy {
3077 type Protocol = BufferCollectionMarker;
3078
3079 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
3080 Self::new(inner)
3081 }
3082
3083 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
3084 self.client.into_channel().map_err(|client| Self { client })
3085 }
3086
3087 fn as_channel(&self) -> &::fidl::AsyncChannel {
3088 self.client.as_channel()
3089 }
3090}
3091
3092impl BufferCollectionProxy {
3093 /// Create a new Proxy for fuchsia.sysmem2/BufferCollection.
3094 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
3095 let protocol_name = <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
3096 Self { client: fidl::client::Client::new(channel, protocol_name) }
3097 }
3098
3099 /// Get a Stream of events from the remote end of the protocol.
3100 ///
3101 /// # Panics
3102 ///
3103 /// Panics if the event stream was already taken.
3104 pub fn take_event_stream(&self) -> BufferCollectionEventStream {
3105 BufferCollectionEventStream { event_receiver: self.client.take_event_receiver() }
3106 }
3107
3108 /// Ensure that previous messages have been received server side. This is
3109 /// particularly useful after previous messages that created new tokens,
3110 /// because a token must be known to the sysmem server before sending the
3111 /// token to another participant.
3112 ///
3113 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
3114 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
3115 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
3116 /// to mitigate the possibility of a hostile/fake
3117 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
3118 /// Another way is to pass the token to
3119 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
3120 /// the token as part of exchanging it for a
3121 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
3122 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
3123 /// of stalling.
3124 ///
3125 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
3126 /// and then starting and completing a `Sync`, it's then safe to send the
3127 /// `BufferCollectionToken` client ends to other participants knowing the
3128 /// server will recognize the tokens when they're sent by the other
3129 /// participants to sysmem in a
3130 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
3131 /// efficient way to create tokens while avoiding unnecessary round trips.
3132 ///
3133 /// Other options include waiting for each
3134 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
3135 /// individually (using separate call to `Sync` after each), or calling
3136 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
3137 /// converted to a `BufferCollection` via
3138 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
3139 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
3140 /// the sync step and can create multiple tokens at once.
3141 pub fn r#sync(
3142 &self,
3143 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
3144 BufferCollectionProxyInterface::r#sync(self)
3145 }
3146
3147 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
3148 ///
3149 /// Normally a participant will convert a `BufferCollectionToken` into a
3150 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
3151 /// `Release` via the token (and then close the channel immediately or
3152 /// shortly later in response to server closing the server end), which
3153 /// avoids causing buffer collection failure. Without a prior `Release`,
3154 /// closing the `BufferCollectionToken` client end will cause buffer
3155 /// collection failure.
3156 ///
3157 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
3158 ///
3159 /// By default the server handles unexpected closure of a
3160 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
3161 /// first) by failing the buffer collection. Partly this is to expedite
3162 /// closing VMO handles to reclaim memory when any participant fails. If a
3163 /// participant would like to cleanly close a `BufferCollection` without
3164 /// causing buffer collection failure, the participant can send `Release`
3165 /// before closing the `BufferCollection` client end. The `Release` can
3166 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
3167 /// buffer collection won't require constraints from this node in order to
3168 /// allocate. If after `SetConstraints`, the constraints are retained and
3169 /// aggregated, despite the lack of `BufferCollection` connection at the
3170 /// time of constraints aggregation.
3171 ///
3172 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
3173 ///
3174 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
3175 /// end (without `Release` first) will trigger failure of the buffer
3176 /// collection. To close a `BufferCollectionTokenGroup` channel without
3177 /// failing the buffer collection, ensure that AllChildrenPresent() has been
3178 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
3179 /// client end.
3180 ///
3181 /// If `Release` occurs before
3182 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
3183 /// buffer collection will fail (triggered by reception of `Release` without
3184 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
3185 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
3186 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
3187 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
3188 /// close requires `AllChildrenPresent` (if not already sent), then
3189 /// `Release`, then close client end.
3190 ///
3191 /// If `Release` occurs after `AllChildrenPresent`, the children and all
3192 /// their constraints remain intact (just as they would if the
3193 /// `BufferCollectionTokenGroup` channel had remained open), and the client
3194 /// end close doesn't trigger buffer collection failure.
3195 ///
3196 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
3197 ///
3198 /// For brevity, the per-channel-protocol paragraphs above ignore the
3199 /// separate failure domain created by
3200 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
3201 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
3202 /// unexpectedly closes (without `Release` first) and that client end is
3203 /// under a failure domain, instead of failing the whole buffer collection,
3204 /// the failure domain is failed, but the buffer collection itself is
3205 /// isolated from failure of the failure domain. Such failure domains can be
3206 /// nested, in which case only the inner-most failure domain in which the
3207 /// `Node` resides fails.
3208 pub fn r#release(&self) -> Result<(), fidl::Error> {
3209 BufferCollectionProxyInterface::r#release(self)
3210 }
3211
3212 /// Set a name for VMOs in this buffer collection.
3213 ///
3214 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
3215 /// will be truncated to fit. The name of the vmo will be suffixed with the
3216 /// buffer index within the collection (if the suffix fits within
3217 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
3218 /// listed in the inspect data.
3219 ///
3220 /// The name only affects VMOs allocated after the name is set; this call
3221 /// does not rename existing VMOs. If multiple clients set different names
3222 /// then the larger priority value will win. Setting a new name with the
3223 /// same priority as a prior name doesn't change the name.
3224 ///
3225 /// All table fields are currently required.
3226 ///
3227 /// + request `priority` The name is only set if this is the first `SetName`
3228 /// or if `priority` is greater than any previous `priority` value in
3229 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
3230 /// + request `name` The name for VMOs created under this buffer collection.
3231 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
3232 BufferCollectionProxyInterface::r#set_name(self, payload)
3233 }
3234
3235 /// Set information about the current client that can be used by sysmem to
3236 /// help diagnose leaking memory and allocation stalls waiting for a
3237 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
3238 ///
3239 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
3240 /// `Node`(s) derived from this `Node`, unless overriden by
3241 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
3242 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
3243 ///
3244 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
3245 /// `Allocator` is the most efficient way to ensure that all
3246 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
3247 /// set, and is also more efficient than separately sending the same debug
3248 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
3249 /// created [`fuchsia.sysmem2/Node`].
3250 ///
3251 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
3252 /// indicate which client is closing their channel first, leading to subtree
3253 /// failure (which can be normal if the purpose of the subtree is over, but
3254 /// if happening earlier than expected, the client-channel-specific name can
3255 /// help diagnose where the failure is first coming from, from sysmem's
3256 /// point of view).
3257 ///
3258 /// All table fields are currently required.
3259 ///
3260 /// + request `name` This can be an arbitrary string, but the current
3261 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
3262 /// + request `id` This can be an arbitrary id, but the current process ID
3263 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
3264 pub fn r#set_debug_client_info(
3265 &self,
3266 mut payload: &NodeSetDebugClientInfoRequest,
3267 ) -> Result<(), fidl::Error> {
3268 BufferCollectionProxyInterface::r#set_debug_client_info(self, payload)
3269 }
3270
3271 /// Sysmem logs a warning if sysmem hasn't seen
3272 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
3273 /// within 5 seconds after creation of a new collection.
3274 ///
3275 /// Clients can call this method to change when the log is printed. If
3276 /// multiple client set the deadline, it's unspecified which deadline will
3277 /// take effect.
3278 ///
3279 /// In most cases the default works well.
3280 ///
3281 /// All table fields are currently required.
3282 ///
3283 /// + request `deadline` The time at which sysmem will start trying to log
3284 /// the warning, unless all constraints are with sysmem by then.
3285 pub fn r#set_debug_timeout_log_deadline(
3286 &self,
3287 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
3288 ) -> Result<(), fidl::Error> {
3289 BufferCollectionProxyInterface::r#set_debug_timeout_log_deadline(self, payload)
3290 }
3291
3292 /// This enables verbose logging for the buffer collection.
3293 ///
3294 /// Verbose logging includes constraints set via
3295 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
3296 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
3297 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
3298 /// the tree of `Node`(s).
3299 ///
3300 /// Normally sysmem prints only a single line complaint when aggregation
3301 /// fails, with just the specific detailed reason that aggregation failed,
3302 /// with little surrounding context. While this is often enough to diagnose
3303 /// a problem if only a small change was made and everything was working
3304 /// before the small change, it's often not particularly helpful for getting
3305 /// a new buffer collection to work for the first time. Especially with
3306 /// more complex trees of nodes, involving things like
3307 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
3308 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
3309 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
3310 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
3311 /// looks like and why it's failing a logical allocation, or why a tree or
3312 /// subtree is failing sooner than expected.
3313 ///
3314 /// The intent of the extra logging is to be acceptable from a performance
3315 /// point of view, under the assumption that verbose logging is only enabled
3316 /// on a low number of buffer collections. If we're not tracking down a bug,
3317 /// we shouldn't send this message.
3318 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
3319 BufferCollectionProxyInterface::r#set_verbose_logging(self)
3320 }
3321
3322 /// This gets a handle that can be used as a parameter to
3323 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
3324 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
3325 /// client obtained this handle from this `Node`.
3326 ///
3327 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
3328 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
3329 /// despite the two calls typically being on different channels.
3330 ///
3331 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
3332 ///
3333 /// All table fields are currently required.
3334 ///
3335 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
3336 /// different `Node` channel, to prove that the client obtained the handle
3337 /// from this `Node`.
3338 pub fn r#get_node_ref(
3339 &self,
3340 ) -> fidl::client::QueryResponseFut<
3341 NodeGetNodeRefResponse,
3342 fidl::encoding::DefaultFuchsiaResourceDialect,
3343 > {
3344 BufferCollectionProxyInterface::r#get_node_ref(self)
3345 }
3346
3347 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
3348 /// rooted at a different child token of a common parent
3349 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
3350 /// passed-in `node_ref`.
3351 ///
3352 /// This call is for assisting with admission control de-duplication, and
3353 /// with debugging.
3354 ///
3355 /// The `node_ref` must be obtained using
3356 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
3357 ///
3358 /// The `node_ref` can be a duplicated handle; it's not necessary to call
3359 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
3360 ///
3361 /// If a calling token may not actually be a valid token at all due to a
3362 /// potentially hostile/untrusted provider of the token, call
3363 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
3364 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
3365 /// never responds due to a calling token not being a real token (not really
3366 /// talking to sysmem). Another option is to call
3367 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
3368 /// which also validates the token along with converting it to a
3369 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
3370 ///
3371 /// All table fields are currently required.
3372 ///
3373 /// - response `is_alternate`
3374 /// - true: The first parent node in common between the calling node and
3375 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
3376 /// that the calling `Node` and the `node_ref` `Node` will not have both
3377 /// their constraints apply - rather sysmem will choose one or the other
3378 /// of the constraints - never both. This is because only one child of
3379 /// a `BufferCollectionTokenGroup` is selected during logical
3380 /// allocation, with only that one child's subtree contributing to
3381 /// constraints aggregation.
3382 /// - false: The first parent node in common between the calling `Node`
3383 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
3384 /// Currently, this means the first parent node in common is a
3385 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
3386 /// `Release`ed). This means that the calling `Node` and the `node_ref`
3387 /// `Node` may have both their constraints apply during constraints
3388 /// aggregation of the logical allocation, if both `Node`(s) are
3389 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
3390 /// this case, there is no `BufferCollectionTokenGroup` that will
3391 /// directly prevent the two `Node`(s) from both being selected and
3392 /// their constraints both aggregated, but even when false, one or both
3393 /// `Node`(s) may still be eliminated from consideration if one or both
3394 /// `Node`(s) has a direct or indirect parent
3395 /// `BufferCollectionTokenGroup` which selects a child subtree other
3396 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
3397 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
3398 /// associated with the same buffer collection as the calling `Node`.
3399 /// Another reason for this error is if the `node_ref` is an
3400 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
3401 /// a real `node_ref` obtained from `GetNodeRef`.
3402 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
3403 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
3404 /// the needed rights expected on a real `node_ref`.
3405 /// * No other failing status codes are returned by this call. However,
3406 /// sysmem may add additional codes in future, so the client should have
3407 /// sensible default handling for any failing status code.
3408 pub fn r#is_alternate_for(
3409 &self,
3410 mut payload: NodeIsAlternateForRequest,
3411 ) -> fidl::client::QueryResponseFut<
3412 NodeIsAlternateForResult,
3413 fidl::encoding::DefaultFuchsiaResourceDialect,
3414 > {
3415 BufferCollectionProxyInterface::r#is_alternate_for(self, payload)
3416 }
3417
3418 /// Get the buffer collection ID. This ID is also available from
3419 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
3420 /// within the collection).
3421 ///
3422 /// This call is mainly useful in situations where we can't convey a
3423 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
3424 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
3425 /// handle, which can be joined back up with a `BufferCollection` client end
3426 /// that was created via a different path. Prefer to convey a
3427 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
3428 ///
3429 /// Trusting a `buffer_collection_id` value from a source other than sysmem
3430 /// is analogous to trusting a koid value from a source other than zircon.
3431 /// Both should be avoided unless really necessary, and both require
3432 /// caution. In some situations it may be reasonable to refer to a
3433 /// pre-established `BufferCollection` by `buffer_collection_id` via a
3434 /// protocol for efficiency reasons, but an incoming value purporting to be
3435 /// a `buffer_collection_id` is not sufficient alone to justify granting the
3436 /// sender of the `buffer_collection_id` any capability. The sender must
3437 /// first prove to a receiver that the sender has/had a VMO or has/had a
3438 /// `BufferCollectionToken` to the same collection by sending a handle that
3439 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
3440 /// `buffer_collection_id` value. The receiver should take care to avoid
3441 /// assuming that a sender had a `BufferCollectionToken` in cases where the
3442 /// sender has only proven that the sender had a VMO.
3443 ///
3444 /// - response `buffer_collection_id` This ID is unique per buffer
3445 /// collection per boot. Each buffer is uniquely identified by the
3446 /// `buffer_collection_id` and `buffer_index` together.
3447 pub fn r#get_buffer_collection_id(
3448 &self,
3449 ) -> fidl::client::QueryResponseFut<
3450 NodeGetBufferCollectionIdResponse,
3451 fidl::encoding::DefaultFuchsiaResourceDialect,
3452 > {
3453 BufferCollectionProxyInterface::r#get_buffer_collection_id(self)
3454 }
3455
3456 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
3457 /// created after this message to weak, which means that a client's `Node`
3458 /// client end (or a child created after this message) is not alone
3459 /// sufficient to keep allocated VMOs alive.
3460 ///
3461 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
3462 /// `close_weak_asap`.
3463 ///
3464 /// This message is only permitted before the `Node` becomes ready for
3465 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
3466 /// * `BufferCollectionToken`: any time
3467 /// * `BufferCollection`: before `SetConstraints`
3468 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
3469 ///
3470 /// Currently, no conversion from strong `Node` to weak `Node` after ready
3471 /// for allocation is provided, but a client can simulate that by creating
3472 /// an additional `Node` before allocation and setting that additional
3473 /// `Node` to weak, and then potentially at some point later sending
3474 /// `Release` and closing the client end of the client's strong `Node`, but
3475 /// keeping the client's weak `Node`.
3476 ///
3477 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
3478 /// collection failure (all `Node` client end(s) will see
3479 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
3480 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
3481 /// this situation until all `Node`(s) are ready for allocation. For initial
3482 /// allocation to succeed, at least one strong `Node` is required to exist
3483 /// at allocation time, but after that client receives VMO handles, that
3484 /// client can `BufferCollection.Release` and close the client end without
3485 /// causing this type of failure.
3486 ///
3487 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
3488 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
3489 /// separately as appropriate.
3490 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
3491 BufferCollectionProxyInterface::r#set_weak(self)
3492 }
3493
3494 /// This indicates to sysmem that the client is prepared to pay attention to
3495 /// `close_weak_asap`.
3496 ///
3497 /// If sent, this message must be before
3498 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
3499 ///
3500 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
3501 /// send this message before `WaitForAllBuffersAllocated`, or a parent
3502 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
3503 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
3504 /// trigger buffer collection failure.
3505 ///
3506 /// This message is necessary because weak sysmem VMOs have not always been
3507 /// a thing, so older clients are not aware of the need to pay attention to
3508 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
3509 /// sysmem weak VMO handles asap. By having this message and requiring
3510 /// participants to indicate their acceptance of this aspect of the overall
3511 /// protocol, we avoid situations where an older client is delivered a weak
3512 /// VMO without any way for sysmem to get that VMO to close quickly later
3513 /// (and on a per-buffer basis).
3514 ///
3515 /// A participant that doesn't handle `close_weak_asap` and also doesn't
3516 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
3517 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
3518 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
3519 /// same participant has a child/delegate which does retrieve VMOs, that
3520 /// child/delegate will need to send `SetWeakOk` before
3521 /// `WaitForAllBuffersAllocated`.
3522 ///
3523 /// + request `for_child_nodes_also` If present and true, this means direct
3524 /// child nodes of this node created after this message plus all
3525 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
3526 /// those nodes. Any child node of this node that was created before this
3527 /// message is not included. This setting is "sticky" in the sense that a
3528 /// subsequent `SetWeakOk` without this bool set to true does not reset
3529 /// the server-side bool. If this creates a problem for a participant, a
3530 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
3531 /// tokens instead, as appropriate. A participant should only set
3532 /// `for_child_nodes_also` true if the participant can really promise to
3533 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
3534 /// weak VMO handles held by participants holding the corresponding child
3535 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
3536 /// which are using sysmem(1) can be weak, despite the clients of those
3537 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
3538 /// direct way to find out about `close_weak_asap`. This only applies to
3539 /// descendents of this `Node` which are using sysmem(1), not to this
3540 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
3541 /// token, which will fail allocation unless an ancestor of this `Node`
3542 /// specified `for_child_nodes_also` true.
3543 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
3544 BufferCollectionProxyInterface::r#set_weak_ok(self, payload)
3545 }
3546
3547 /// The server_end will be closed after this `Node` and any child nodes have
3548 /// have released their buffer counts, making those counts available for
3549 /// reservation by a different `Node` via
3550 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
3551 ///
3552 /// The `Node` buffer counts may not be released until the entire tree of
3553 /// `Node`(s) is closed or failed, because
3554 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
3555 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
3556 /// `Node` buffer counts remain reserved until the orphaned node is later
3557 /// cleaned up.
3558 ///
3559 /// If the `Node` exceeds a fairly large number of attached eventpair server
3560 /// ends, a log message will indicate this and the `Node` (and the
3561 /// appropriate) sub-tree will fail.
3562 ///
3563 /// The `server_end` will remain open when
3564 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
3565 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
3566 /// [`fuchsia.sysmem2/BufferCollection`].
3567 ///
3568 /// This message can also be used with a
3569 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
3570 pub fn r#attach_node_tracking(
3571 &self,
3572 mut payload: NodeAttachNodeTrackingRequest,
3573 ) -> Result<(), fidl::Error> {
3574 BufferCollectionProxyInterface::r#attach_node_tracking(self, payload)
3575 }
3576
3577 /// Provide [`fuchsia.sysmem2/BufferCollectionConstraints`] to the buffer
3578 /// collection.
3579 ///
3580 /// A participant may only call
3581 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] up to once per
3582 /// [`fuchsia.sysmem2/BufferCollection`].
3583 ///
3584 /// For buffer allocation to be attempted, all holders of a
3585 /// `BufferCollection` client end need to call `SetConstraints` before
3586 /// sysmem will attempt to allocate buffers.
3587 pub fn r#set_constraints(
3588 &self,
3589 mut payload: BufferCollectionSetConstraintsRequest,
3590 ) -> Result<(), fidl::Error> {
3591 BufferCollectionProxyInterface::r#set_constraints(self, payload)
3592 }
3593
3594 /// Wait until all buffers are allocated.
3595 ///
3596 /// This FIDL call completes when buffers have been allocated, or completes
3597 /// with some failure detail if allocation has been attempted but failed.
3598 ///
3599 /// The following must occur before buffers will be allocated:
3600 /// * All [`fuchsia.sysmem2/BufferCollectionToken`](s) of the buffer
3601 /// collection must be turned in via `BindSharedCollection` to get a
3602 /// [`fuchsia.sysmem2/BufferCollection`] (for brevity, this is assuming
3603 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`] isn't being used),
3604 /// or have had [`fuchsia.sysmem2/BufferCollectionToken.Release`] sent
3605 /// to them.
3606 /// * All [`fuchsia.sysmem2/BufferCollection`](s) of the buffer collection
3607 /// must have had [`fuchsia.sysmem2/BufferCollection.SetConstraints`]
3608 /// sent to them, or had [`fuchsia.sysmem2/BufferCollection.Release`]
3609 /// sent to them.
3610 ///
3611 /// - result `buffer_collection_info` The VMO handles and other related
3612 /// info.
3613 /// * error `[fuchsia.sysmem2/Error.NO_MEMORY]` The request is valid but
3614 /// cannot be fulfilled due to resource exhaustion.
3615 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION`] The request is
3616 /// malformed.
3617 /// * error `[fuchsia.sysmem2/Error.CONSTRAINTS_INTERSECTION_EMPTY`] The
3618 /// request is valid but cannot be satisfied, perhaps due to hardware
3619 /// limitations. This can happen if participants have incompatible
3620 /// constraints (empty intersection, roughly speaking). See the log for
3621 /// more info. In cases where a participant could potentially be treated
3622 /// as optional, see [`BufferCollectionTokenGroup`]. When using
3623 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], this will be the
3624 /// error code if there aren't enough buffers in the pre-existing
3625 /// collection to satisfy the constraints set on the attached token and
3626 /// any sub-tree of tokens derived from the attached token.
3627 pub fn r#wait_for_all_buffers_allocated(
3628 &self,
3629 ) -> fidl::client::QueryResponseFut<
3630 BufferCollectionWaitForAllBuffersAllocatedResult,
3631 fidl::encoding::DefaultFuchsiaResourceDialect,
3632 > {
3633 BufferCollectionProxyInterface::r#wait_for_all_buffers_allocated(self)
3634 }
3635
3636 /// Checks whether all the buffers have been allocated, in a polling
3637 /// fashion.
3638 ///
3639 /// * If the buffer collection has been allocated, returns success.
3640 /// * If the buffer collection failed allocation, returns the same
3641 /// [`fuchsia.sysmem2/Error`] as
3642 /// [`fuchsia.sysmem2/BufferCollection/WaitForAllBuffersAllocated`] would
3643 /// return.
3644 /// * error [`fuchsia.sysmem2/Error.PENDING`] The buffer collection hasn't
3645 /// attempted allocation yet. This means that WaitForAllBuffersAllocated
3646 /// would not respond quickly.
3647 pub fn r#check_all_buffers_allocated(
3648 &self,
3649 ) -> fidl::client::QueryResponseFut<
3650 BufferCollectionCheckAllBuffersAllocatedResult,
3651 fidl::encoding::DefaultFuchsiaResourceDialect,
3652 > {
3653 BufferCollectionProxyInterface::r#check_all_buffers_allocated(self)
3654 }
3655
3656 /// Create a new token to add a new participant to an existing logical
3657 /// buffer collection, if the existing collection's buffer counts,
3658 /// constraints, and participants allow.
3659 ///
3660 /// This can be useful in replacing a failed participant, and/or in
3661 /// adding/re-adding a participant after buffers have already been
3662 /// allocated.
3663 ///
3664 /// When [`fuchsia.sysmem2/BufferCollection.AttachToken`] is used, the sub
3665 /// tree rooted at the attached [`fuchsia.sysmem2/BufferCollectionToken`]
3666 /// goes through the normal procedure of setting constraints or closing
3667 /// [`fuchsia.sysmem2/Node`](s), and then appearing to allocate buffers from
3668 /// clients' point of view, despite the possibility that all the buffers
3669 /// were actually allocated previously. This process is called "logical
3670 /// allocation". Most instances of "allocation" in docs for other messages
3671 /// can also be read as "allocation or logical allocation" while remaining
3672 /// valid, but we just say "allocation" in most places for brevity/clarity
3673 /// of explanation, with the details of "logical allocation" left for the
3674 /// docs here on `AttachToken`.
3675 ///
3676 /// Failure of an attached `Node` does not propagate to the parent of the
3677 /// attached `Node`. More generally, failure of a child `Node` is blocked
3678 /// from reaching its parent `Node` if the child is attached, or if the
3679 /// child is dispensable and the failure occurred after logical allocation
3680 /// (see [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`]).
3681 ///
3682 /// A participant may in some scenarios choose to initially use a
3683 /// dispensable token for a given instance of a delegate participant, and
3684 /// then later if the first instance of that delegate participant fails, a
3685 /// new second instance of that delegate participant my be given a token
3686 /// created with `AttachToken`.
3687 ///
3688 /// From the point of view of the [`fuchsia.sysmem2/BufferCollectionToken`]
3689 /// client end, the token acts like any other token. The client can
3690 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] the token as needed,
3691 /// and can send the token to a different process/participant. The
3692 /// `BufferCollectionToken` `Node` should be converted to a
3693 /// `BufferCollection` `Node` as normal by sending
3694 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or can be closed
3695 /// without causing subtree failure by sending
3696 /// [`fuchsia.sysmem2/BufferCollectionToken.Release`]. Assuming the former,
3697 /// the [`fuchsia.sysmem2/BufferCollection.SetConstraints`] message or
3698 /// [`fuchsia.sysmem2/BufferCollection.Release`] message should be sent to
3699 /// the `BufferCollection`.
3700 ///
3701 /// Within the subtree, a success result from
3702 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`] means
3703 /// the subtree participants' constraints were satisfiable using the
3704 /// already-existing buffer collection, the already-established
3705 /// [`fuchsia.sysmem2/BufferCollectionInfo`] including image format
3706 /// constraints, and the already-existing other participants (already added
3707 /// via successful logical allocation) and their specified buffer counts in
3708 /// their constraints. A failure result means the new participants'
3709 /// constraints cannot be satisfied using the existing buffer collection and
3710 /// its already-added participants. Creating a new collection instead may
3711 /// allow all participants' constraints to be satisfied, assuming
3712 /// `SetDispensable` is used in place of `AttachToken`, or a normal token is
3713 /// used.
3714 ///
3715 /// A token created with `AttachToken` performs constraints aggregation with
3716 /// all constraints currently in effect on the buffer collection, plus the
3717 /// attached token under consideration plus child tokens under the attached
3718 /// token which are not themselves an attached token or under such a token.
3719 /// Further subtrees under this subtree are considered for logical
3720 /// allocation only after this subtree has completed logical allocation.
3721 ///
3722 /// Assignment of existing buffers to participants'
3723 /// [`fuchsia.sysmem2/BufferCollectionConstraints.min_buffer_count_for_camping`]
3724 /// etc is first-come first-served, but a child can't logically allocate
3725 /// before all its parents have sent `SetConstraints`.
3726 ///
3727 /// See also [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`], which
3728 /// in contrast to `AttachToken`, has the created token `Node` + child
3729 /// `Node`(s) (in the created subtree but not in any subtree under this
3730 /// subtree) participate in constraints aggregation along with its parent
3731 /// during the parent's allocation or logical allocation.
3732 ///
3733 /// Similar to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], the
3734 /// newly created token needs to be [`fuchsia.sysmem2/Node.Sync`]ed to
3735 /// sysmem before the new token can be passed to `BindSharedCollection`. The
3736 /// `Sync` of the new token can be accomplished with
3737 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after converting the created
3738 /// `BufferCollectionToken` to a `BufferCollection`. Alternately,
3739 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on the new token also
3740 /// works. Or using [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`]
3741 /// works. As usual, a `BufferCollectionToken.Sync` can be started after any
3742 /// `BufferCollectionToken.Duplicate` messages have been sent via the newly
3743 /// created token, to also sync those additional tokens to sysmem using a
3744 /// single round-trip.
3745 ///
3746 /// All table fields are currently required.
3747 ///
3748 /// + request `rights_attentuation_mask` This allows attenuating the VMO
3749 /// rights of the subtree. These values for `rights_attenuation_mask`
3750 /// result in no attenuation (note that 0 is not on this list):
3751 /// + ZX_RIGHT_SAME_RIGHTS (preferred)
3752 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
3753 /// + request `token_request` The server end of the `BufferCollectionToken`
3754 /// channel. The client retains the client end.
3755 pub fn r#attach_token(
3756 &self,
3757 mut payload: BufferCollectionAttachTokenRequest,
3758 ) -> Result<(), fidl::Error> {
3759 BufferCollectionProxyInterface::r#attach_token(self, payload)
3760 }
3761
3762 /// Set up an eventpair to be signalled (`ZX_EVENTPAIR_PEER_CLOSED`) when
3763 /// buffers have been allocated and only the specified number of buffers (or
3764 /// fewer) remain in the buffer collection.
3765 ///
3766 /// [`fuchsia.sysmem2/BufferCollection.AttachLifetimeTracking`] allows a
3767 /// client to wait until an old buffer collection is fully or mostly
3768 /// deallocated before attempting allocation of a new buffer collection. The
3769 /// eventpair is only signalled when the buffers of this collection have
3770 /// been fully deallocated (not just un-referenced by clients, but all the
3771 /// memory consumed by those buffers has been fully reclaimed/recycled), or
3772 /// when allocation or logical allocation fails for the tree or subtree
3773 /// including this [`fuchsia.sysmem2/BufferCollection`].
3774 ///
3775 /// The eventpair won't be signalled until allocation or logical allocation
3776 /// has completed; until then, the collection's current buffer count is
3777 /// ignored.
3778 ///
3779 /// If logical allocation fails for an attached subtree (using
3780 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]), the server end of the
3781 /// eventpair will close during that failure regardless of the number of
3782 /// buffers potenitally allocated in the overall buffer collection. This is
3783 /// for logical allocation consistency with normal allocation.
3784 ///
3785 /// The lifetime signalled by this event includes asynchronous cleanup of
3786 /// allocated buffers, and this asynchronous cleanup cannot occur until all
3787 /// holders of VMO handles to the buffers have closed those VMO handles.
3788 /// Therefore, clients should take care not to become blocked forever
3789 /// waiting for `ZX_EVENTPAIR_PEER_CLOSED` to be signalled if any of the
3790 /// participants using the logical buffer collection (including the waiter
3791 /// itself) are less trusted, less reliable, or potentially blocked by the
3792 /// wait itself. Waiting asynchronously is recommended. Setting a deadline
3793 /// for the client wait may be prudent, depending on details of how the
3794 /// collection and/or its VMOs are used or shared. Failure to allocate a
3795 /// new/replacement buffer collection is better than getting stuck forever.
3796 ///
3797 /// The sysmem server itself intentionally does not perform any waiting on
3798 /// already-failed collections' VMOs to finish cleaning up before attempting
3799 /// a new allocation, and the sysmem server intentionally doesn't retry
3800 /// allocation if a new allocation fails due to out of memory, even if that
3801 /// failure is potentially due to continued existence of an old collection's
3802 /// VMOs. This `AttachLifetimeTracking` message is how an initiator can
3803 /// mitigate too much overlap of old VMO lifetimes with new VMO lifetimes,
3804 /// as long as the waiting client is careful to not create a deadlock.
3805 ///
3806 /// Continued existence of old collections that are still cleaning up is not
3807 /// the only reason that a new allocation may fail due to insufficient
3808 /// memory, even if the new allocation is allocating physically contiguous
3809 /// buffers. Overall system memory pressure can also be the cause of failure
3810 /// to allocate a new collection. See also
3811 /// [`fuchsia.memorypressure/Provider`].
3812 ///
3813 /// `AttachLifetimeTracking` is meant to be compatible with other protocols
3814 /// with a similar `AttachLifetimeTracking` message; duplicates of the same
3815 /// `eventpair` handle (server end) can be sent via more than one
3816 /// `AttachLifetimeTracking` message to different protocols, and the
3817 /// `ZX_EVENTPAIR_PEER_CLOSED` will be signalled for the client end when all
3818 /// the conditions are met (all holders of duplicates have closed their
3819 /// server end handle(s)). Also, thanks to how eventpair endponts work, the
3820 /// client end can (also) be duplicated without preventing the
3821 /// `ZX_EVENTPAIR_PEER_CLOSED` signal.
3822 ///
3823 /// The server intentionally doesn't "trust" any signals set on the
3824 /// `server_end`. This mechanism intentionally uses only
3825 /// `ZX_EVENTPAIR_PEER_CLOSED` set on the client end, which can't be set
3826 /// "early", and is only set when all handles to the server end eventpair
3827 /// are closed. No meaning is associated with any of the other signals, and
3828 /// clients should ignore any other signal bits on either end of the
3829 /// `eventpair`.
3830 ///
3831 /// The `server_end` may lack `ZX_RIGHT_SIGNAL` or `ZX_RIGHT_SIGNAL_PEER`,
3832 /// but must have `ZX_RIGHT_DUPLICATE` (and must have `ZX_RIGHT_TRANSFER` to
3833 /// transfer without causing `BufferCollection` channel failure).
3834 ///
3835 /// All table fields are currently required.
3836 ///
3837 /// + request `server_end` This eventpair handle will be closed by the
3838 /// sysmem server when buffers have been allocated initially and the
3839 /// number of buffers is then less than or equal to `buffers_remaining`.
3840 /// + request `buffers_remaining` Wait for all but `buffers_remaining` (or
3841 /// fewer) buffers to be fully deallocated. A number greater than zero can
3842 /// be useful in situations where a known number of buffers are
3843 /// intentionally not closed so that the data can continue to be used,
3844 /// such as for keeping the last available video frame displayed in the UI
3845 /// even if the video stream was using protected output buffers. It's
3846 /// outside the scope of the `BufferCollection` interface (at least for
3847 /// now) to determine how many buffers may be held without closing, but
3848 /// it'll typically be in the range 0-2.
3849 pub fn r#attach_lifetime_tracking(
3850 &self,
3851 mut payload: BufferCollectionAttachLifetimeTrackingRequest,
3852 ) -> Result<(), fidl::Error> {
3853 BufferCollectionProxyInterface::r#attach_lifetime_tracking(self, payload)
3854 }
3855}
3856
3857impl BufferCollectionProxyInterface for BufferCollectionProxy {
3858 type SyncResponseFut =
3859 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
3860 fn r#sync(&self) -> Self::SyncResponseFut {
3861 fn _decode(
3862 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
3863 ) -> Result<(), fidl::Error> {
3864 let _response = fidl::client::decode_transaction_body::<
3865 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
3866 fidl::encoding::DefaultFuchsiaResourceDialect,
3867 0x11ac2555cf575b54,
3868 >(_buf?)?
3869 .into_result::<BufferCollectionMarker>("sync")?;
3870 Ok(_response)
3871 }
3872 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
3873 (),
3874 0x11ac2555cf575b54,
3875 fidl::encoding::DynamicFlags::FLEXIBLE,
3876 _decode,
3877 )
3878 }
3879
3880 fn r#release(&self) -> Result<(), fidl::Error> {
3881 self.client.send::<fidl::encoding::EmptyPayload>(
3882 (),
3883 0x6a5cae7d6d6e04c6,
3884 fidl::encoding::DynamicFlags::FLEXIBLE,
3885 )
3886 }
3887
3888 fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
3889 self.client.send::<NodeSetNameRequest>(
3890 payload,
3891 0xb41f1624f48c1e9,
3892 fidl::encoding::DynamicFlags::FLEXIBLE,
3893 )
3894 }
3895
3896 fn r#set_debug_client_info(
3897 &self,
3898 mut payload: &NodeSetDebugClientInfoRequest,
3899 ) -> Result<(), fidl::Error> {
3900 self.client.send::<NodeSetDebugClientInfoRequest>(
3901 payload,
3902 0x5cde8914608d99b1,
3903 fidl::encoding::DynamicFlags::FLEXIBLE,
3904 )
3905 }
3906
3907 fn r#set_debug_timeout_log_deadline(
3908 &self,
3909 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
3910 ) -> Result<(), fidl::Error> {
3911 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
3912 payload,
3913 0x716b0af13d5c0806,
3914 fidl::encoding::DynamicFlags::FLEXIBLE,
3915 )
3916 }
3917
3918 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
3919 self.client.send::<fidl::encoding::EmptyPayload>(
3920 (),
3921 0x5209c77415b4dfad,
3922 fidl::encoding::DynamicFlags::FLEXIBLE,
3923 )
3924 }
3925
3926 type GetNodeRefResponseFut = fidl::client::QueryResponseFut<
3927 NodeGetNodeRefResponse,
3928 fidl::encoding::DefaultFuchsiaResourceDialect,
3929 >;
3930 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
3931 fn _decode(
3932 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
3933 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
3934 let _response = fidl::client::decode_transaction_body::<
3935 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
3936 fidl::encoding::DefaultFuchsiaResourceDialect,
3937 0x5b3d0e51614df053,
3938 >(_buf?)?
3939 .into_result::<BufferCollectionMarker>("get_node_ref")?;
3940 Ok(_response)
3941 }
3942 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
3943 (),
3944 0x5b3d0e51614df053,
3945 fidl::encoding::DynamicFlags::FLEXIBLE,
3946 _decode,
3947 )
3948 }
3949
3950 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
3951 NodeIsAlternateForResult,
3952 fidl::encoding::DefaultFuchsiaResourceDialect,
3953 >;
3954 fn r#is_alternate_for(
3955 &self,
3956 mut payload: NodeIsAlternateForRequest,
3957 ) -> Self::IsAlternateForResponseFut {
3958 fn _decode(
3959 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
3960 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
3961 let _response = fidl::client::decode_transaction_body::<
3962 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
3963 fidl::encoding::DefaultFuchsiaResourceDialect,
3964 0x3a58e00157e0825,
3965 >(_buf?)?
3966 .into_result::<BufferCollectionMarker>("is_alternate_for")?;
3967 Ok(_response.map(|x| x))
3968 }
3969 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
3970 &mut payload,
3971 0x3a58e00157e0825,
3972 fidl::encoding::DynamicFlags::FLEXIBLE,
3973 _decode,
3974 )
3975 }
3976
3977 type GetBufferCollectionIdResponseFut = fidl::client::QueryResponseFut<
3978 NodeGetBufferCollectionIdResponse,
3979 fidl::encoding::DefaultFuchsiaResourceDialect,
3980 >;
3981 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut {
3982 fn _decode(
3983 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
3984 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
3985 let _response = fidl::client::decode_transaction_body::<
3986 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
3987 fidl::encoding::DefaultFuchsiaResourceDialect,
3988 0x77d19a494b78ba8c,
3989 >(_buf?)?
3990 .into_result::<BufferCollectionMarker>("get_buffer_collection_id")?;
3991 Ok(_response)
3992 }
3993 self.client.send_query_and_decode::<
3994 fidl::encoding::EmptyPayload,
3995 NodeGetBufferCollectionIdResponse,
3996 >(
3997 (),
3998 0x77d19a494b78ba8c,
3999 fidl::encoding::DynamicFlags::FLEXIBLE,
4000 _decode,
4001 )
4002 }
4003
4004 fn r#set_weak(&self) -> Result<(), fidl::Error> {
4005 self.client.send::<fidl::encoding::EmptyPayload>(
4006 (),
4007 0x22dd3ea514eeffe1,
4008 fidl::encoding::DynamicFlags::FLEXIBLE,
4009 )
4010 }
4011
4012 fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
4013 self.client.send::<NodeSetWeakOkRequest>(
4014 &mut payload,
4015 0x38a44fc4d7724be9,
4016 fidl::encoding::DynamicFlags::FLEXIBLE,
4017 )
4018 }
4019
4020 fn r#attach_node_tracking(
4021 &self,
4022 mut payload: NodeAttachNodeTrackingRequest,
4023 ) -> Result<(), fidl::Error> {
4024 self.client.send::<NodeAttachNodeTrackingRequest>(
4025 &mut payload,
4026 0x3f22f2a293d3cdac,
4027 fidl::encoding::DynamicFlags::FLEXIBLE,
4028 )
4029 }
4030
4031 fn r#set_constraints(
4032 &self,
4033 mut payload: BufferCollectionSetConstraintsRequest,
4034 ) -> Result<(), fidl::Error> {
4035 self.client.send::<BufferCollectionSetConstraintsRequest>(
4036 &mut payload,
4037 0x1fde0f19d650197b,
4038 fidl::encoding::DynamicFlags::FLEXIBLE,
4039 )
4040 }
4041
4042 type WaitForAllBuffersAllocatedResponseFut = fidl::client::QueryResponseFut<
4043 BufferCollectionWaitForAllBuffersAllocatedResult,
4044 fidl::encoding::DefaultFuchsiaResourceDialect,
4045 >;
4046 fn r#wait_for_all_buffers_allocated(&self) -> Self::WaitForAllBuffersAllocatedResponseFut {
4047 fn _decode(
4048 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
4049 ) -> Result<BufferCollectionWaitForAllBuffersAllocatedResult, fidl::Error> {
4050 let _response = fidl::client::decode_transaction_body::<
4051 fidl::encoding::FlexibleResultType<
4052 BufferCollectionWaitForAllBuffersAllocatedResponse,
4053 Error,
4054 >,
4055 fidl::encoding::DefaultFuchsiaResourceDialect,
4056 0x62300344b61404e,
4057 >(_buf?)?
4058 .into_result::<BufferCollectionMarker>("wait_for_all_buffers_allocated")?;
4059 Ok(_response.map(|x| x))
4060 }
4061 self.client.send_query_and_decode::<
4062 fidl::encoding::EmptyPayload,
4063 BufferCollectionWaitForAllBuffersAllocatedResult,
4064 >(
4065 (),
4066 0x62300344b61404e,
4067 fidl::encoding::DynamicFlags::FLEXIBLE,
4068 _decode,
4069 )
4070 }
4071
4072 type CheckAllBuffersAllocatedResponseFut = fidl::client::QueryResponseFut<
4073 BufferCollectionCheckAllBuffersAllocatedResult,
4074 fidl::encoding::DefaultFuchsiaResourceDialect,
4075 >;
4076 fn r#check_all_buffers_allocated(&self) -> Self::CheckAllBuffersAllocatedResponseFut {
4077 fn _decode(
4078 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
4079 ) -> Result<BufferCollectionCheckAllBuffersAllocatedResult, fidl::Error> {
4080 let _response = fidl::client::decode_transaction_body::<
4081 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
4082 fidl::encoding::DefaultFuchsiaResourceDialect,
4083 0x35a5fe77ce939c10,
4084 >(_buf?)?
4085 .into_result::<BufferCollectionMarker>("check_all_buffers_allocated")?;
4086 Ok(_response.map(|x| x))
4087 }
4088 self.client.send_query_and_decode::<
4089 fidl::encoding::EmptyPayload,
4090 BufferCollectionCheckAllBuffersAllocatedResult,
4091 >(
4092 (),
4093 0x35a5fe77ce939c10,
4094 fidl::encoding::DynamicFlags::FLEXIBLE,
4095 _decode,
4096 )
4097 }
4098
4099 fn r#attach_token(
4100 &self,
4101 mut payload: BufferCollectionAttachTokenRequest,
4102 ) -> Result<(), fidl::Error> {
4103 self.client.send::<BufferCollectionAttachTokenRequest>(
4104 &mut payload,
4105 0x46ac7d0008492982,
4106 fidl::encoding::DynamicFlags::FLEXIBLE,
4107 )
4108 }
4109
4110 fn r#attach_lifetime_tracking(
4111 &self,
4112 mut payload: BufferCollectionAttachLifetimeTrackingRequest,
4113 ) -> Result<(), fidl::Error> {
4114 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
4115 &mut payload,
4116 0x3ecb510113116dcf,
4117 fidl::encoding::DynamicFlags::FLEXIBLE,
4118 )
4119 }
4120}
4121
4122pub struct BufferCollectionEventStream {
4123 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
4124}
4125
4126impl std::marker::Unpin for BufferCollectionEventStream {}
4127
4128impl futures::stream::FusedStream for BufferCollectionEventStream {
4129 fn is_terminated(&self) -> bool {
4130 self.event_receiver.is_terminated()
4131 }
4132}
4133
4134impl futures::Stream for BufferCollectionEventStream {
4135 type Item = Result<BufferCollectionEvent, fidl::Error>;
4136
4137 fn poll_next(
4138 mut self: std::pin::Pin<&mut Self>,
4139 cx: &mut std::task::Context<'_>,
4140 ) -> std::task::Poll<Option<Self::Item>> {
4141 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
4142 &mut self.event_receiver,
4143 cx
4144 )?) {
4145 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionEvent::decode(buf))),
4146 None => std::task::Poll::Ready(None),
4147 }
4148 }
4149}
4150
4151#[derive(Debug)]
4152pub enum BufferCollectionEvent {
4153 #[non_exhaustive]
4154 _UnknownEvent {
4155 /// Ordinal of the event that was sent.
4156 ordinal: u64,
4157 },
4158}
4159
4160impl BufferCollectionEvent {
4161 /// Decodes a message buffer as a [`BufferCollectionEvent`].
4162 fn decode(
4163 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
4164 ) -> Result<BufferCollectionEvent, fidl::Error> {
4165 let (bytes, _handles) = buf.split_mut();
4166 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
4167 debug_assert_eq!(tx_header.tx_id, 0);
4168 match tx_header.ordinal {
4169 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
4170 Ok(BufferCollectionEvent::_UnknownEvent { ordinal: tx_header.ordinal })
4171 }
4172 _ => Err(fidl::Error::UnknownOrdinal {
4173 ordinal: tx_header.ordinal,
4174 protocol_name:
4175 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
4176 }),
4177 }
4178 }
4179}
4180
4181/// A Stream of incoming requests for fuchsia.sysmem2/BufferCollection.
4182pub struct BufferCollectionRequestStream {
4183 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
4184 is_terminated: bool,
4185}
4186
4187impl std::marker::Unpin for BufferCollectionRequestStream {}
4188
4189impl futures::stream::FusedStream for BufferCollectionRequestStream {
4190 fn is_terminated(&self) -> bool {
4191 self.is_terminated
4192 }
4193}
4194
4195impl fidl::endpoints::RequestStream for BufferCollectionRequestStream {
4196 type Protocol = BufferCollectionMarker;
4197 type ControlHandle = BufferCollectionControlHandle;
4198
4199 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
4200 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
4201 }
4202
4203 fn control_handle(&self) -> Self::ControlHandle {
4204 BufferCollectionControlHandle { inner: self.inner.clone() }
4205 }
4206
4207 fn into_inner(
4208 self,
4209 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
4210 {
4211 (self.inner, self.is_terminated)
4212 }
4213
4214 fn from_inner(
4215 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
4216 is_terminated: bool,
4217 ) -> Self {
4218 Self { inner, is_terminated }
4219 }
4220}
4221
4222impl futures::Stream for BufferCollectionRequestStream {
4223 type Item = Result<BufferCollectionRequest, fidl::Error>;
4224
4225 fn poll_next(
4226 mut self: std::pin::Pin<&mut Self>,
4227 cx: &mut std::task::Context<'_>,
4228 ) -> std::task::Poll<Option<Self::Item>> {
4229 let this = &mut *self;
4230 if this.inner.check_shutdown(cx) {
4231 this.is_terminated = true;
4232 return std::task::Poll::Ready(None);
4233 }
4234 if this.is_terminated {
4235 panic!("polled BufferCollectionRequestStream after completion");
4236 }
4237 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
4238 |bytes, handles| {
4239 match this.inner.channel().read_etc(cx, bytes, handles) {
4240 std::task::Poll::Ready(Ok(())) => {}
4241 std::task::Poll::Pending => return std::task::Poll::Pending,
4242 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
4243 this.is_terminated = true;
4244 return std::task::Poll::Ready(None);
4245 }
4246 std::task::Poll::Ready(Err(e)) => {
4247 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
4248 e.into(),
4249 ))));
4250 }
4251 }
4252
4253 // A message has been received from the channel
4254 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
4255
4256 std::task::Poll::Ready(Some(match header.ordinal {
4257 0x11ac2555cf575b54 => {
4258 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4259 let mut req = fidl::new_empty!(
4260 fidl::encoding::EmptyPayload,
4261 fidl::encoding::DefaultFuchsiaResourceDialect
4262 );
4263 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4264 let control_handle =
4265 BufferCollectionControlHandle { inner: this.inner.clone() };
4266 Ok(BufferCollectionRequest::Sync {
4267 responder: BufferCollectionSyncResponder {
4268 control_handle: std::mem::ManuallyDrop::new(control_handle),
4269 tx_id: header.tx_id,
4270 },
4271 })
4272 }
4273 0x6a5cae7d6d6e04c6 => {
4274 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4275 let mut req = fidl::new_empty!(
4276 fidl::encoding::EmptyPayload,
4277 fidl::encoding::DefaultFuchsiaResourceDialect
4278 );
4279 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4280 let control_handle =
4281 BufferCollectionControlHandle { inner: this.inner.clone() };
4282 Ok(BufferCollectionRequest::Release { control_handle })
4283 }
4284 0xb41f1624f48c1e9 => {
4285 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4286 let mut req = fidl::new_empty!(
4287 NodeSetNameRequest,
4288 fidl::encoding::DefaultFuchsiaResourceDialect
4289 );
4290 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
4291 let control_handle =
4292 BufferCollectionControlHandle { inner: this.inner.clone() };
4293 Ok(BufferCollectionRequest::SetName { payload: req, control_handle })
4294 }
4295 0x5cde8914608d99b1 => {
4296 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4297 let mut req = fidl::new_empty!(
4298 NodeSetDebugClientInfoRequest,
4299 fidl::encoding::DefaultFuchsiaResourceDialect
4300 );
4301 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
4302 let control_handle =
4303 BufferCollectionControlHandle { inner: this.inner.clone() };
4304 Ok(BufferCollectionRequest::SetDebugClientInfo {
4305 payload: req,
4306 control_handle,
4307 })
4308 }
4309 0x716b0af13d5c0806 => {
4310 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4311 let mut req = fidl::new_empty!(
4312 NodeSetDebugTimeoutLogDeadlineRequest,
4313 fidl::encoding::DefaultFuchsiaResourceDialect
4314 );
4315 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
4316 let control_handle =
4317 BufferCollectionControlHandle { inner: this.inner.clone() };
4318 Ok(BufferCollectionRequest::SetDebugTimeoutLogDeadline {
4319 payload: req,
4320 control_handle,
4321 })
4322 }
4323 0x5209c77415b4dfad => {
4324 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4325 let mut req = fidl::new_empty!(
4326 fidl::encoding::EmptyPayload,
4327 fidl::encoding::DefaultFuchsiaResourceDialect
4328 );
4329 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4330 let control_handle =
4331 BufferCollectionControlHandle { inner: this.inner.clone() };
4332 Ok(BufferCollectionRequest::SetVerboseLogging { control_handle })
4333 }
4334 0x5b3d0e51614df053 => {
4335 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4336 let mut req = fidl::new_empty!(
4337 fidl::encoding::EmptyPayload,
4338 fidl::encoding::DefaultFuchsiaResourceDialect
4339 );
4340 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4341 let control_handle =
4342 BufferCollectionControlHandle { inner: this.inner.clone() };
4343 Ok(BufferCollectionRequest::GetNodeRef {
4344 responder: BufferCollectionGetNodeRefResponder {
4345 control_handle: std::mem::ManuallyDrop::new(control_handle),
4346 tx_id: header.tx_id,
4347 },
4348 })
4349 }
4350 0x3a58e00157e0825 => {
4351 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4352 let mut req = fidl::new_empty!(
4353 NodeIsAlternateForRequest,
4354 fidl::encoding::DefaultFuchsiaResourceDialect
4355 );
4356 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
4357 let control_handle =
4358 BufferCollectionControlHandle { inner: this.inner.clone() };
4359 Ok(BufferCollectionRequest::IsAlternateFor {
4360 payload: req,
4361 responder: BufferCollectionIsAlternateForResponder {
4362 control_handle: std::mem::ManuallyDrop::new(control_handle),
4363 tx_id: header.tx_id,
4364 },
4365 })
4366 }
4367 0x77d19a494b78ba8c => {
4368 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4369 let mut req = fidl::new_empty!(
4370 fidl::encoding::EmptyPayload,
4371 fidl::encoding::DefaultFuchsiaResourceDialect
4372 );
4373 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4374 let control_handle =
4375 BufferCollectionControlHandle { inner: this.inner.clone() };
4376 Ok(BufferCollectionRequest::GetBufferCollectionId {
4377 responder: BufferCollectionGetBufferCollectionIdResponder {
4378 control_handle: std::mem::ManuallyDrop::new(control_handle),
4379 tx_id: header.tx_id,
4380 },
4381 })
4382 }
4383 0x22dd3ea514eeffe1 => {
4384 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4385 let mut req = fidl::new_empty!(
4386 fidl::encoding::EmptyPayload,
4387 fidl::encoding::DefaultFuchsiaResourceDialect
4388 );
4389 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4390 let control_handle =
4391 BufferCollectionControlHandle { inner: this.inner.clone() };
4392 Ok(BufferCollectionRequest::SetWeak { control_handle })
4393 }
4394 0x38a44fc4d7724be9 => {
4395 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4396 let mut req = fidl::new_empty!(
4397 NodeSetWeakOkRequest,
4398 fidl::encoding::DefaultFuchsiaResourceDialect
4399 );
4400 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetWeakOkRequest>(&header, _body_bytes, handles, &mut req)?;
4401 let control_handle =
4402 BufferCollectionControlHandle { inner: this.inner.clone() };
4403 Ok(BufferCollectionRequest::SetWeakOk { payload: req, control_handle })
4404 }
4405 0x3f22f2a293d3cdac => {
4406 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4407 let mut req = fidl::new_empty!(
4408 NodeAttachNodeTrackingRequest,
4409 fidl::encoding::DefaultFuchsiaResourceDialect
4410 );
4411 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeAttachNodeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
4412 let control_handle =
4413 BufferCollectionControlHandle { inner: this.inner.clone() };
4414 Ok(BufferCollectionRequest::AttachNodeTracking {
4415 payload: req,
4416 control_handle,
4417 })
4418 }
4419 0x1fde0f19d650197b => {
4420 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4421 let mut req = fidl::new_empty!(
4422 BufferCollectionSetConstraintsRequest,
4423 fidl::encoding::DefaultFuchsiaResourceDialect
4424 );
4425 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionSetConstraintsRequest>(&header, _body_bytes, handles, &mut req)?;
4426 let control_handle =
4427 BufferCollectionControlHandle { inner: this.inner.clone() };
4428 Ok(BufferCollectionRequest::SetConstraints { payload: req, control_handle })
4429 }
4430 0x62300344b61404e => {
4431 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4432 let mut req = fidl::new_empty!(
4433 fidl::encoding::EmptyPayload,
4434 fidl::encoding::DefaultFuchsiaResourceDialect
4435 );
4436 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4437 let control_handle =
4438 BufferCollectionControlHandle { inner: this.inner.clone() };
4439 Ok(BufferCollectionRequest::WaitForAllBuffersAllocated {
4440 responder: BufferCollectionWaitForAllBuffersAllocatedResponder {
4441 control_handle: std::mem::ManuallyDrop::new(control_handle),
4442 tx_id: header.tx_id,
4443 },
4444 })
4445 }
4446 0x35a5fe77ce939c10 => {
4447 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4448 let mut req = fidl::new_empty!(
4449 fidl::encoding::EmptyPayload,
4450 fidl::encoding::DefaultFuchsiaResourceDialect
4451 );
4452 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4453 let control_handle =
4454 BufferCollectionControlHandle { inner: this.inner.clone() };
4455 Ok(BufferCollectionRequest::CheckAllBuffersAllocated {
4456 responder: BufferCollectionCheckAllBuffersAllocatedResponder {
4457 control_handle: std::mem::ManuallyDrop::new(control_handle),
4458 tx_id: header.tx_id,
4459 },
4460 })
4461 }
4462 0x46ac7d0008492982 => {
4463 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4464 let mut req = fidl::new_empty!(
4465 BufferCollectionAttachTokenRequest,
4466 fidl::encoding::DefaultFuchsiaResourceDialect
4467 );
4468 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachTokenRequest>(&header, _body_bytes, handles, &mut req)?;
4469 let control_handle =
4470 BufferCollectionControlHandle { inner: this.inner.clone() };
4471 Ok(BufferCollectionRequest::AttachToken { payload: req, control_handle })
4472 }
4473 0x3ecb510113116dcf => {
4474 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4475 let mut req = fidl::new_empty!(
4476 BufferCollectionAttachLifetimeTrackingRequest,
4477 fidl::encoding::DefaultFuchsiaResourceDialect
4478 );
4479 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachLifetimeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
4480 let control_handle =
4481 BufferCollectionControlHandle { inner: this.inner.clone() };
4482 Ok(BufferCollectionRequest::AttachLifetimeTracking {
4483 payload: req,
4484 control_handle,
4485 })
4486 }
4487 _ if header.tx_id == 0
4488 && header
4489 .dynamic_flags()
4490 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
4491 {
4492 Ok(BufferCollectionRequest::_UnknownMethod {
4493 ordinal: header.ordinal,
4494 control_handle: BufferCollectionControlHandle {
4495 inner: this.inner.clone(),
4496 },
4497 method_type: fidl::MethodType::OneWay,
4498 })
4499 }
4500 _ if header
4501 .dynamic_flags()
4502 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
4503 {
4504 this.inner.send_framework_err(
4505 fidl::encoding::FrameworkErr::UnknownMethod,
4506 header.tx_id,
4507 header.ordinal,
4508 header.dynamic_flags(),
4509 (bytes, handles),
4510 )?;
4511 Ok(BufferCollectionRequest::_UnknownMethod {
4512 ordinal: header.ordinal,
4513 control_handle: BufferCollectionControlHandle {
4514 inner: this.inner.clone(),
4515 },
4516 method_type: fidl::MethodType::TwoWay,
4517 })
4518 }
4519 _ => Err(fidl::Error::UnknownOrdinal {
4520 ordinal: header.ordinal,
4521 protocol_name:
4522 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
4523 }),
4524 }))
4525 },
4526 )
4527 }
4528}
4529
4530/// [`fuchsia.sysmem2/BufferCollection`] is a connection directly from a
4531/// participant to sysmem re. a buffer collection; often the buffer collection
4532/// is shared with other participants which have their own `BufferCollection`
4533/// client end(s) associated with the same buffer collection. In other words,
4534/// an instance of the `BufferCollection` interface is a view of a buffer
4535/// collection, not the buffer collection itself.
4536///
4537/// The `BufferCollection` connection exists to facilitate async indication of
4538/// when the buffer collection has been populated with buffers.
4539///
4540/// Also, the channel's closure by the sysmem server is an indication to the
4541/// client that the client should close all VMO handles that were obtained from
4542/// the `BufferCollection` ASAP.
4543///
4544/// Some buffer collections can use enough memory that it can be worth avoiding
4545/// allocation overlap (in time) using
4546/// [`fuchsia.sysmem2/BufferCollection.AttachLifetimeTracking`] so that the
4547/// initiator can tell when enough buffers of the buffer collection have been
4548/// fully deallocated prior to the initiator allocating a new buffer collection.
4549///
4550/// Epitaphs are not used in this protocol.
4551#[derive(Debug)]
4552pub enum BufferCollectionRequest {
4553 /// Ensure that previous messages have been received server side. This is
4554 /// particularly useful after previous messages that created new tokens,
4555 /// because a token must be known to the sysmem server before sending the
4556 /// token to another participant.
4557 ///
4558 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
4559 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
4560 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
4561 /// to mitigate the possibility of a hostile/fake
4562 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
4563 /// Another way is to pass the token to
4564 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
4565 /// the token as part of exchanging it for a
4566 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
4567 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
4568 /// of stalling.
4569 ///
4570 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
4571 /// and then starting and completing a `Sync`, it's then safe to send the
4572 /// `BufferCollectionToken` client ends to other participants knowing the
4573 /// server will recognize the tokens when they're sent by the other
4574 /// participants to sysmem in a
4575 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
4576 /// efficient way to create tokens while avoiding unnecessary round trips.
4577 ///
4578 /// Other options include waiting for each
4579 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
4580 /// individually (using separate call to `Sync` after each), or calling
4581 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
4582 /// converted to a `BufferCollection` via
4583 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
4584 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
4585 /// the sync step and can create multiple tokens at once.
4586 Sync { responder: BufferCollectionSyncResponder },
4587 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
4588 ///
4589 /// Normally a participant will convert a `BufferCollectionToken` into a
4590 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
4591 /// `Release` via the token (and then close the channel immediately or
4592 /// shortly later in response to server closing the server end), which
4593 /// avoids causing buffer collection failure. Without a prior `Release`,
4594 /// closing the `BufferCollectionToken` client end will cause buffer
4595 /// collection failure.
4596 ///
4597 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
4598 ///
4599 /// By default the server handles unexpected closure of a
4600 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
4601 /// first) by failing the buffer collection. Partly this is to expedite
4602 /// closing VMO handles to reclaim memory when any participant fails. If a
4603 /// participant would like to cleanly close a `BufferCollection` without
4604 /// causing buffer collection failure, the participant can send `Release`
4605 /// before closing the `BufferCollection` client end. The `Release` can
4606 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
4607 /// buffer collection won't require constraints from this node in order to
4608 /// allocate. If after `SetConstraints`, the constraints are retained and
4609 /// aggregated, despite the lack of `BufferCollection` connection at the
4610 /// time of constraints aggregation.
4611 ///
4612 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
4613 ///
4614 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
4615 /// end (without `Release` first) will trigger failure of the buffer
4616 /// collection. To close a `BufferCollectionTokenGroup` channel without
4617 /// failing the buffer collection, ensure that AllChildrenPresent() has been
4618 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
4619 /// client end.
4620 ///
4621 /// If `Release` occurs before
4622 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
4623 /// buffer collection will fail (triggered by reception of `Release` without
4624 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
4625 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
4626 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
4627 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
4628 /// close requires `AllChildrenPresent` (if not already sent), then
4629 /// `Release`, then close client end.
4630 ///
4631 /// If `Release` occurs after `AllChildrenPresent`, the children and all
4632 /// their constraints remain intact (just as they would if the
4633 /// `BufferCollectionTokenGroup` channel had remained open), and the client
4634 /// end close doesn't trigger buffer collection failure.
4635 ///
4636 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
4637 ///
4638 /// For brevity, the per-channel-protocol paragraphs above ignore the
4639 /// separate failure domain created by
4640 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
4641 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
4642 /// unexpectedly closes (without `Release` first) and that client end is
4643 /// under a failure domain, instead of failing the whole buffer collection,
4644 /// the failure domain is failed, but the buffer collection itself is
4645 /// isolated from failure of the failure domain. Such failure domains can be
4646 /// nested, in which case only the inner-most failure domain in which the
4647 /// `Node` resides fails.
4648 Release { control_handle: BufferCollectionControlHandle },
4649 /// Set a name for VMOs in this buffer collection.
4650 ///
4651 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
4652 /// will be truncated to fit. The name of the vmo will be suffixed with the
4653 /// buffer index within the collection (if the suffix fits within
4654 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
4655 /// listed in the inspect data.
4656 ///
4657 /// The name only affects VMOs allocated after the name is set; this call
4658 /// does not rename existing VMOs. If multiple clients set different names
4659 /// then the larger priority value will win. Setting a new name with the
4660 /// same priority as a prior name doesn't change the name.
4661 ///
4662 /// All table fields are currently required.
4663 ///
4664 /// + request `priority` The name is only set if this is the first `SetName`
4665 /// or if `priority` is greater than any previous `priority` value in
4666 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
4667 /// + request `name` The name for VMOs created under this buffer collection.
4668 SetName { payload: NodeSetNameRequest, control_handle: BufferCollectionControlHandle },
4669 /// Set information about the current client that can be used by sysmem to
4670 /// help diagnose leaking memory and allocation stalls waiting for a
4671 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
4672 ///
4673 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
4674 /// `Node`(s) derived from this `Node`, unless overriden by
4675 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
4676 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
4677 ///
4678 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
4679 /// `Allocator` is the most efficient way to ensure that all
4680 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
4681 /// set, and is also more efficient than separately sending the same debug
4682 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
4683 /// created [`fuchsia.sysmem2/Node`].
4684 ///
4685 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
4686 /// indicate which client is closing their channel first, leading to subtree
4687 /// failure (which can be normal if the purpose of the subtree is over, but
4688 /// if happening earlier than expected, the client-channel-specific name can
4689 /// help diagnose where the failure is first coming from, from sysmem's
4690 /// point of view).
4691 ///
4692 /// All table fields are currently required.
4693 ///
4694 /// + request `name` This can be an arbitrary string, but the current
4695 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
4696 /// + request `id` This can be an arbitrary id, but the current process ID
4697 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
4698 SetDebugClientInfo {
4699 payload: NodeSetDebugClientInfoRequest,
4700 control_handle: BufferCollectionControlHandle,
4701 },
4702 /// Sysmem logs a warning if sysmem hasn't seen
4703 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
4704 /// within 5 seconds after creation of a new collection.
4705 ///
4706 /// Clients can call this method to change when the log is printed. If
4707 /// multiple client set the deadline, it's unspecified which deadline will
4708 /// take effect.
4709 ///
4710 /// In most cases the default works well.
4711 ///
4712 /// All table fields are currently required.
4713 ///
4714 /// + request `deadline` The time at which sysmem will start trying to log
4715 /// the warning, unless all constraints are with sysmem by then.
4716 SetDebugTimeoutLogDeadline {
4717 payload: NodeSetDebugTimeoutLogDeadlineRequest,
4718 control_handle: BufferCollectionControlHandle,
4719 },
4720 /// This enables verbose logging for the buffer collection.
4721 ///
4722 /// Verbose logging includes constraints set via
4723 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
4724 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
4725 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
4726 /// the tree of `Node`(s).
4727 ///
4728 /// Normally sysmem prints only a single line complaint when aggregation
4729 /// fails, with just the specific detailed reason that aggregation failed,
4730 /// with little surrounding context. While this is often enough to diagnose
4731 /// a problem if only a small change was made and everything was working
4732 /// before the small change, it's often not particularly helpful for getting
4733 /// a new buffer collection to work for the first time. Especially with
4734 /// more complex trees of nodes, involving things like
4735 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
4736 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
4737 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
4738 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
4739 /// looks like and why it's failing a logical allocation, or why a tree or
4740 /// subtree is failing sooner than expected.
4741 ///
4742 /// The intent of the extra logging is to be acceptable from a performance
4743 /// point of view, under the assumption that verbose logging is only enabled
4744 /// on a low number of buffer collections. If we're not tracking down a bug,
4745 /// we shouldn't send this message.
4746 SetVerboseLogging { control_handle: BufferCollectionControlHandle },
4747 /// This gets a handle that can be used as a parameter to
4748 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
4749 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
4750 /// client obtained this handle from this `Node`.
4751 ///
4752 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
4753 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
4754 /// despite the two calls typically being on different channels.
4755 ///
4756 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
4757 ///
4758 /// All table fields are currently required.
4759 ///
4760 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
4761 /// different `Node` channel, to prove that the client obtained the handle
4762 /// from this `Node`.
4763 GetNodeRef { responder: BufferCollectionGetNodeRefResponder },
4764 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
4765 /// rooted at a different child token of a common parent
4766 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
4767 /// passed-in `node_ref`.
4768 ///
4769 /// This call is for assisting with admission control de-duplication, and
4770 /// with debugging.
4771 ///
4772 /// The `node_ref` must be obtained using
4773 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
4774 ///
4775 /// The `node_ref` can be a duplicated handle; it's not necessary to call
4776 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
4777 ///
4778 /// If a calling token may not actually be a valid token at all due to a
4779 /// potentially hostile/untrusted provider of the token, call
4780 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
4781 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
4782 /// never responds due to a calling token not being a real token (not really
4783 /// talking to sysmem). Another option is to call
4784 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
4785 /// which also validates the token along with converting it to a
4786 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
4787 ///
4788 /// All table fields are currently required.
4789 ///
4790 /// - response `is_alternate`
4791 /// - true: The first parent node in common between the calling node and
4792 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
4793 /// that the calling `Node` and the `node_ref` `Node` will not have both
4794 /// their constraints apply - rather sysmem will choose one or the other
4795 /// of the constraints - never both. This is because only one child of
4796 /// a `BufferCollectionTokenGroup` is selected during logical
4797 /// allocation, with only that one child's subtree contributing to
4798 /// constraints aggregation.
4799 /// - false: The first parent node in common between the calling `Node`
4800 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
4801 /// Currently, this means the first parent node in common is a
4802 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
4803 /// `Release`ed). This means that the calling `Node` and the `node_ref`
4804 /// `Node` may have both their constraints apply during constraints
4805 /// aggregation of the logical allocation, if both `Node`(s) are
4806 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
4807 /// this case, there is no `BufferCollectionTokenGroup` that will
4808 /// directly prevent the two `Node`(s) from both being selected and
4809 /// their constraints both aggregated, but even when false, one or both
4810 /// `Node`(s) may still be eliminated from consideration if one or both
4811 /// `Node`(s) has a direct or indirect parent
4812 /// `BufferCollectionTokenGroup` which selects a child subtree other
4813 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
4814 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
4815 /// associated with the same buffer collection as the calling `Node`.
4816 /// Another reason for this error is if the `node_ref` is an
4817 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
4818 /// a real `node_ref` obtained from `GetNodeRef`.
4819 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
4820 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
4821 /// the needed rights expected on a real `node_ref`.
4822 /// * No other failing status codes are returned by this call. However,
4823 /// sysmem may add additional codes in future, so the client should have
4824 /// sensible default handling for any failing status code.
4825 IsAlternateFor {
4826 payload: NodeIsAlternateForRequest,
4827 responder: BufferCollectionIsAlternateForResponder,
4828 },
4829 /// Get the buffer collection ID. This ID is also available from
4830 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
4831 /// within the collection).
4832 ///
4833 /// This call is mainly useful in situations where we can't convey a
4834 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
4835 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
4836 /// handle, which can be joined back up with a `BufferCollection` client end
4837 /// that was created via a different path. Prefer to convey a
4838 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
4839 ///
4840 /// Trusting a `buffer_collection_id` value from a source other than sysmem
4841 /// is analogous to trusting a koid value from a source other than zircon.
4842 /// Both should be avoided unless really necessary, and both require
4843 /// caution. In some situations it may be reasonable to refer to a
4844 /// pre-established `BufferCollection` by `buffer_collection_id` via a
4845 /// protocol for efficiency reasons, but an incoming value purporting to be
4846 /// a `buffer_collection_id` is not sufficient alone to justify granting the
4847 /// sender of the `buffer_collection_id` any capability. The sender must
4848 /// first prove to a receiver that the sender has/had a VMO or has/had a
4849 /// `BufferCollectionToken` to the same collection by sending a handle that
4850 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
4851 /// `buffer_collection_id` value. The receiver should take care to avoid
4852 /// assuming that a sender had a `BufferCollectionToken` in cases where the
4853 /// sender has only proven that the sender had a VMO.
4854 ///
4855 /// - response `buffer_collection_id` This ID is unique per buffer
4856 /// collection per boot. Each buffer is uniquely identified by the
4857 /// `buffer_collection_id` and `buffer_index` together.
4858 GetBufferCollectionId { responder: BufferCollectionGetBufferCollectionIdResponder },
4859 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
4860 /// created after this message to weak, which means that a client's `Node`
4861 /// client end (or a child created after this message) is not alone
4862 /// sufficient to keep allocated VMOs alive.
4863 ///
4864 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
4865 /// `close_weak_asap`.
4866 ///
4867 /// This message is only permitted before the `Node` becomes ready for
4868 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
4869 /// * `BufferCollectionToken`: any time
4870 /// * `BufferCollection`: before `SetConstraints`
4871 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
4872 ///
4873 /// Currently, no conversion from strong `Node` to weak `Node` after ready
4874 /// for allocation is provided, but a client can simulate that by creating
4875 /// an additional `Node` before allocation and setting that additional
4876 /// `Node` to weak, and then potentially at some point later sending
4877 /// `Release` and closing the client end of the client's strong `Node`, but
4878 /// keeping the client's weak `Node`.
4879 ///
4880 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
4881 /// collection failure (all `Node` client end(s) will see
4882 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
4883 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
4884 /// this situation until all `Node`(s) are ready for allocation. For initial
4885 /// allocation to succeed, at least one strong `Node` is required to exist
4886 /// at allocation time, but after that client receives VMO handles, that
4887 /// client can `BufferCollection.Release` and close the client end without
4888 /// causing this type of failure.
4889 ///
4890 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
4891 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
4892 /// separately as appropriate.
4893 SetWeak { control_handle: BufferCollectionControlHandle },
4894 /// This indicates to sysmem that the client is prepared to pay attention to
4895 /// `close_weak_asap`.
4896 ///
4897 /// If sent, this message must be before
4898 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
4899 ///
4900 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
4901 /// send this message before `WaitForAllBuffersAllocated`, or a parent
4902 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
4903 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
4904 /// trigger buffer collection failure.
4905 ///
4906 /// This message is necessary because weak sysmem VMOs have not always been
4907 /// a thing, so older clients are not aware of the need to pay attention to
4908 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
4909 /// sysmem weak VMO handles asap. By having this message and requiring
4910 /// participants to indicate their acceptance of this aspect of the overall
4911 /// protocol, we avoid situations where an older client is delivered a weak
4912 /// VMO without any way for sysmem to get that VMO to close quickly later
4913 /// (and on a per-buffer basis).
4914 ///
4915 /// A participant that doesn't handle `close_weak_asap` and also doesn't
4916 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
4917 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
4918 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
4919 /// same participant has a child/delegate which does retrieve VMOs, that
4920 /// child/delegate will need to send `SetWeakOk` before
4921 /// `WaitForAllBuffersAllocated`.
4922 ///
4923 /// + request `for_child_nodes_also` If present and true, this means direct
4924 /// child nodes of this node created after this message plus all
4925 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
4926 /// those nodes. Any child node of this node that was created before this
4927 /// message is not included. This setting is "sticky" in the sense that a
4928 /// subsequent `SetWeakOk` without this bool set to true does not reset
4929 /// the server-side bool. If this creates a problem for a participant, a
4930 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
4931 /// tokens instead, as appropriate. A participant should only set
4932 /// `for_child_nodes_also` true if the participant can really promise to
4933 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
4934 /// weak VMO handles held by participants holding the corresponding child
4935 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
4936 /// which are using sysmem(1) can be weak, despite the clients of those
4937 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
4938 /// direct way to find out about `close_weak_asap`. This only applies to
4939 /// descendents of this `Node` which are using sysmem(1), not to this
4940 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
4941 /// token, which will fail allocation unless an ancestor of this `Node`
4942 /// specified `for_child_nodes_also` true.
4943 SetWeakOk { payload: NodeSetWeakOkRequest, control_handle: BufferCollectionControlHandle },
4944 /// The server_end will be closed after this `Node` and any child nodes have
4945 /// have released their buffer counts, making those counts available for
4946 /// reservation by a different `Node` via
4947 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
4948 ///
4949 /// The `Node` buffer counts may not be released until the entire tree of
4950 /// `Node`(s) is closed or failed, because
4951 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
4952 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
4953 /// `Node` buffer counts remain reserved until the orphaned node is later
4954 /// cleaned up.
4955 ///
4956 /// If the `Node` exceeds a fairly large number of attached eventpair server
4957 /// ends, a log message will indicate this and the `Node` (and the
4958 /// appropriate) sub-tree will fail.
4959 ///
4960 /// The `server_end` will remain open when
4961 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
4962 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
4963 /// [`fuchsia.sysmem2/BufferCollection`].
4964 ///
4965 /// This message can also be used with a
4966 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
4967 AttachNodeTracking {
4968 payload: NodeAttachNodeTrackingRequest,
4969 control_handle: BufferCollectionControlHandle,
4970 },
4971 /// Provide [`fuchsia.sysmem2/BufferCollectionConstraints`] to the buffer
4972 /// collection.
4973 ///
4974 /// A participant may only call
4975 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] up to once per
4976 /// [`fuchsia.sysmem2/BufferCollection`].
4977 ///
4978 /// For buffer allocation to be attempted, all holders of a
4979 /// `BufferCollection` client end need to call `SetConstraints` before
4980 /// sysmem will attempt to allocate buffers.
4981 SetConstraints {
4982 payload: BufferCollectionSetConstraintsRequest,
4983 control_handle: BufferCollectionControlHandle,
4984 },
4985 /// Wait until all buffers are allocated.
4986 ///
4987 /// This FIDL call completes when buffers have been allocated, or completes
4988 /// with some failure detail if allocation has been attempted but failed.
4989 ///
4990 /// The following must occur before buffers will be allocated:
4991 /// * All [`fuchsia.sysmem2/BufferCollectionToken`](s) of the buffer
4992 /// collection must be turned in via `BindSharedCollection` to get a
4993 /// [`fuchsia.sysmem2/BufferCollection`] (for brevity, this is assuming
4994 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`] isn't being used),
4995 /// or have had [`fuchsia.sysmem2/BufferCollectionToken.Release`] sent
4996 /// to them.
4997 /// * All [`fuchsia.sysmem2/BufferCollection`](s) of the buffer collection
4998 /// must have had [`fuchsia.sysmem2/BufferCollection.SetConstraints`]
4999 /// sent to them, or had [`fuchsia.sysmem2/BufferCollection.Release`]
5000 /// sent to them.
5001 ///
5002 /// - result `buffer_collection_info` The VMO handles and other related
5003 /// info.
5004 /// * error `[fuchsia.sysmem2/Error.NO_MEMORY]` The request is valid but
5005 /// cannot be fulfilled due to resource exhaustion.
5006 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION`] The request is
5007 /// malformed.
5008 /// * error `[fuchsia.sysmem2/Error.CONSTRAINTS_INTERSECTION_EMPTY`] The
5009 /// request is valid but cannot be satisfied, perhaps due to hardware
5010 /// limitations. This can happen if participants have incompatible
5011 /// constraints (empty intersection, roughly speaking). See the log for
5012 /// more info. In cases where a participant could potentially be treated
5013 /// as optional, see [`BufferCollectionTokenGroup`]. When using
5014 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], this will be the
5015 /// error code if there aren't enough buffers in the pre-existing
5016 /// collection to satisfy the constraints set on the attached token and
5017 /// any sub-tree of tokens derived from the attached token.
5018 WaitForAllBuffersAllocated { responder: BufferCollectionWaitForAllBuffersAllocatedResponder },
5019 /// Checks whether all the buffers have been allocated, in a polling
5020 /// fashion.
5021 ///
5022 /// * If the buffer collection has been allocated, returns success.
5023 /// * If the buffer collection failed allocation, returns the same
5024 /// [`fuchsia.sysmem2/Error`] as
5025 /// [`fuchsia.sysmem2/BufferCollection/WaitForAllBuffersAllocated`] would
5026 /// return.
5027 /// * error [`fuchsia.sysmem2/Error.PENDING`] The buffer collection hasn't
5028 /// attempted allocation yet. This means that WaitForAllBuffersAllocated
5029 /// would not respond quickly.
5030 CheckAllBuffersAllocated { responder: BufferCollectionCheckAllBuffersAllocatedResponder },
5031 /// Create a new token to add a new participant to an existing logical
5032 /// buffer collection, if the existing collection's buffer counts,
5033 /// constraints, and participants allow.
5034 ///
5035 /// This can be useful in replacing a failed participant, and/or in
5036 /// adding/re-adding a participant after buffers have already been
5037 /// allocated.
5038 ///
5039 /// When [`fuchsia.sysmem2/BufferCollection.AttachToken`] is used, the sub
5040 /// tree rooted at the attached [`fuchsia.sysmem2/BufferCollectionToken`]
5041 /// goes through the normal procedure of setting constraints or closing
5042 /// [`fuchsia.sysmem2/Node`](s), and then appearing to allocate buffers from
5043 /// clients' point of view, despite the possibility that all the buffers
5044 /// were actually allocated previously. This process is called "logical
5045 /// allocation". Most instances of "allocation" in docs for other messages
5046 /// can also be read as "allocation or logical allocation" while remaining
5047 /// valid, but we just say "allocation" in most places for brevity/clarity
5048 /// of explanation, with the details of "logical allocation" left for the
5049 /// docs here on `AttachToken`.
5050 ///
5051 /// Failure of an attached `Node` does not propagate to the parent of the
5052 /// attached `Node`. More generally, failure of a child `Node` is blocked
5053 /// from reaching its parent `Node` if the child is attached, or if the
5054 /// child is dispensable and the failure occurred after logical allocation
5055 /// (see [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`]).
5056 ///
5057 /// A participant may in some scenarios choose to initially use a
5058 /// dispensable token for a given instance of a delegate participant, and
5059 /// then later if the first instance of that delegate participant fails, a
5060 /// new second instance of that delegate participant my be given a token
5061 /// created with `AttachToken`.
5062 ///
5063 /// From the point of view of the [`fuchsia.sysmem2/BufferCollectionToken`]
5064 /// client end, the token acts like any other token. The client can
5065 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] the token as needed,
5066 /// and can send the token to a different process/participant. The
5067 /// `BufferCollectionToken` `Node` should be converted to a
5068 /// `BufferCollection` `Node` as normal by sending
5069 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or can be closed
5070 /// without causing subtree failure by sending
5071 /// [`fuchsia.sysmem2/BufferCollectionToken.Release`]. Assuming the former,
5072 /// the [`fuchsia.sysmem2/BufferCollection.SetConstraints`] message or
5073 /// [`fuchsia.sysmem2/BufferCollection.Release`] message should be sent to
5074 /// the `BufferCollection`.
5075 ///
5076 /// Within the subtree, a success result from
5077 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`] means
5078 /// the subtree participants' constraints were satisfiable using the
5079 /// already-existing buffer collection, the already-established
5080 /// [`fuchsia.sysmem2/BufferCollectionInfo`] including image format
5081 /// constraints, and the already-existing other participants (already added
5082 /// via successful logical allocation) and their specified buffer counts in
5083 /// their constraints. A failure result means the new participants'
5084 /// constraints cannot be satisfied using the existing buffer collection and
5085 /// its already-added participants. Creating a new collection instead may
5086 /// allow all participants' constraints to be satisfied, assuming
5087 /// `SetDispensable` is used in place of `AttachToken`, or a normal token is
5088 /// used.
5089 ///
5090 /// A token created with `AttachToken` performs constraints aggregation with
5091 /// all constraints currently in effect on the buffer collection, plus the
5092 /// attached token under consideration plus child tokens under the attached
5093 /// token which are not themselves an attached token or under such a token.
5094 /// Further subtrees under this subtree are considered for logical
5095 /// allocation only after this subtree has completed logical allocation.
5096 ///
5097 /// Assignment of existing buffers to participants'
5098 /// [`fuchsia.sysmem2/BufferCollectionConstraints.min_buffer_count_for_camping`]
5099 /// etc is first-come first-served, but a child can't logically allocate
5100 /// before all its parents have sent `SetConstraints`.
5101 ///
5102 /// See also [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`], which
5103 /// in contrast to `AttachToken`, has the created token `Node` + child
5104 /// `Node`(s) (in the created subtree but not in any subtree under this
5105 /// subtree) participate in constraints aggregation along with its parent
5106 /// during the parent's allocation or logical allocation.
5107 ///
5108 /// Similar to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], the
5109 /// newly created token needs to be [`fuchsia.sysmem2/Node.Sync`]ed to
5110 /// sysmem before the new token can be passed to `BindSharedCollection`. The
5111 /// `Sync` of the new token can be accomplished with
5112 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after converting the created
5113 /// `BufferCollectionToken` to a `BufferCollection`. Alternately,
5114 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on the new token also
5115 /// works. Or using [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`]
5116 /// works. As usual, a `BufferCollectionToken.Sync` can be started after any
5117 /// `BufferCollectionToken.Duplicate` messages have been sent via the newly
5118 /// created token, to also sync those additional tokens to sysmem using a
5119 /// single round-trip.
5120 ///
5121 /// All table fields are currently required.
5122 ///
5123 /// + request `rights_attentuation_mask` This allows attenuating the VMO
5124 /// rights of the subtree. These values for `rights_attenuation_mask`
5125 /// result in no attenuation (note that 0 is not on this list):
5126 /// + ZX_RIGHT_SAME_RIGHTS (preferred)
5127 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
5128 /// + request `token_request` The server end of the `BufferCollectionToken`
5129 /// channel. The client retains the client end.
5130 AttachToken {
5131 payload: BufferCollectionAttachTokenRequest,
5132 control_handle: BufferCollectionControlHandle,
5133 },
5134 /// Set up an eventpair to be signalled (`ZX_EVENTPAIR_PEER_CLOSED`) when
5135 /// buffers have been allocated and only the specified number of buffers (or
5136 /// fewer) remain in the buffer collection.
5137 ///
5138 /// [`fuchsia.sysmem2/BufferCollection.AttachLifetimeTracking`] allows a
5139 /// client to wait until an old buffer collection is fully or mostly
5140 /// deallocated before attempting allocation of a new buffer collection. The
5141 /// eventpair is only signalled when the buffers of this collection have
5142 /// been fully deallocated (not just un-referenced by clients, but all the
5143 /// memory consumed by those buffers has been fully reclaimed/recycled), or
5144 /// when allocation or logical allocation fails for the tree or subtree
5145 /// including this [`fuchsia.sysmem2/BufferCollection`].
5146 ///
5147 /// The eventpair won't be signalled until allocation or logical allocation
5148 /// has completed; until then, the collection's current buffer count is
5149 /// ignored.
5150 ///
5151 /// If logical allocation fails for an attached subtree (using
5152 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]), the server end of the
5153 /// eventpair will close during that failure regardless of the number of
5154 /// buffers potenitally allocated in the overall buffer collection. This is
5155 /// for logical allocation consistency with normal allocation.
5156 ///
5157 /// The lifetime signalled by this event includes asynchronous cleanup of
5158 /// allocated buffers, and this asynchronous cleanup cannot occur until all
5159 /// holders of VMO handles to the buffers have closed those VMO handles.
5160 /// Therefore, clients should take care not to become blocked forever
5161 /// waiting for `ZX_EVENTPAIR_PEER_CLOSED` to be signalled if any of the
5162 /// participants using the logical buffer collection (including the waiter
5163 /// itself) are less trusted, less reliable, or potentially blocked by the
5164 /// wait itself. Waiting asynchronously is recommended. Setting a deadline
5165 /// for the client wait may be prudent, depending on details of how the
5166 /// collection and/or its VMOs are used or shared. Failure to allocate a
5167 /// new/replacement buffer collection is better than getting stuck forever.
5168 ///
5169 /// The sysmem server itself intentionally does not perform any waiting on
5170 /// already-failed collections' VMOs to finish cleaning up before attempting
5171 /// a new allocation, and the sysmem server intentionally doesn't retry
5172 /// allocation if a new allocation fails due to out of memory, even if that
5173 /// failure is potentially due to continued existence of an old collection's
5174 /// VMOs. This `AttachLifetimeTracking` message is how an initiator can
5175 /// mitigate too much overlap of old VMO lifetimes with new VMO lifetimes,
5176 /// as long as the waiting client is careful to not create a deadlock.
5177 ///
5178 /// Continued existence of old collections that are still cleaning up is not
5179 /// the only reason that a new allocation may fail due to insufficient
5180 /// memory, even if the new allocation is allocating physically contiguous
5181 /// buffers. Overall system memory pressure can also be the cause of failure
5182 /// to allocate a new collection. See also
5183 /// [`fuchsia.memorypressure/Provider`].
5184 ///
5185 /// `AttachLifetimeTracking` is meant to be compatible with other protocols
5186 /// with a similar `AttachLifetimeTracking` message; duplicates of the same
5187 /// `eventpair` handle (server end) can be sent via more than one
5188 /// `AttachLifetimeTracking` message to different protocols, and the
5189 /// `ZX_EVENTPAIR_PEER_CLOSED` will be signalled for the client end when all
5190 /// the conditions are met (all holders of duplicates have closed their
5191 /// server end handle(s)). Also, thanks to how eventpair endponts work, the
5192 /// client end can (also) be duplicated without preventing the
5193 /// `ZX_EVENTPAIR_PEER_CLOSED` signal.
5194 ///
5195 /// The server intentionally doesn't "trust" any signals set on the
5196 /// `server_end`. This mechanism intentionally uses only
5197 /// `ZX_EVENTPAIR_PEER_CLOSED` set on the client end, which can't be set
5198 /// "early", and is only set when all handles to the server end eventpair
5199 /// are closed. No meaning is associated with any of the other signals, and
5200 /// clients should ignore any other signal bits on either end of the
5201 /// `eventpair`.
5202 ///
5203 /// The `server_end` may lack `ZX_RIGHT_SIGNAL` or `ZX_RIGHT_SIGNAL_PEER`,
5204 /// but must have `ZX_RIGHT_DUPLICATE` (and must have `ZX_RIGHT_TRANSFER` to
5205 /// transfer without causing `BufferCollection` channel failure).
5206 ///
5207 /// All table fields are currently required.
5208 ///
5209 /// + request `server_end` This eventpair handle will be closed by the
5210 /// sysmem server when buffers have been allocated initially and the
5211 /// number of buffers is then less than or equal to `buffers_remaining`.
5212 /// + request `buffers_remaining` Wait for all but `buffers_remaining` (or
5213 /// fewer) buffers to be fully deallocated. A number greater than zero can
5214 /// be useful in situations where a known number of buffers are
5215 /// intentionally not closed so that the data can continue to be used,
5216 /// such as for keeping the last available video frame displayed in the UI
5217 /// even if the video stream was using protected output buffers. It's
5218 /// outside the scope of the `BufferCollection` interface (at least for
5219 /// now) to determine how many buffers may be held without closing, but
5220 /// it'll typically be in the range 0-2.
5221 AttachLifetimeTracking {
5222 payload: BufferCollectionAttachLifetimeTrackingRequest,
5223 control_handle: BufferCollectionControlHandle,
5224 },
5225 /// An interaction was received which does not match any known method.
5226 #[non_exhaustive]
5227 _UnknownMethod {
5228 /// Ordinal of the method that was called.
5229 ordinal: u64,
5230 control_handle: BufferCollectionControlHandle,
5231 method_type: fidl::MethodType,
5232 },
5233}
5234
5235impl BufferCollectionRequest {
5236 #[allow(irrefutable_let_patterns)]
5237 pub fn into_sync(self) -> Option<(BufferCollectionSyncResponder)> {
5238 if let BufferCollectionRequest::Sync { responder } = self {
5239 Some((responder))
5240 } else {
5241 None
5242 }
5243 }
5244
5245 #[allow(irrefutable_let_patterns)]
5246 pub fn into_release(self) -> Option<(BufferCollectionControlHandle)> {
5247 if let BufferCollectionRequest::Release { control_handle } = self {
5248 Some((control_handle))
5249 } else {
5250 None
5251 }
5252 }
5253
5254 #[allow(irrefutable_let_patterns)]
5255 pub fn into_set_name(self) -> Option<(NodeSetNameRequest, BufferCollectionControlHandle)> {
5256 if let BufferCollectionRequest::SetName { payload, control_handle } = self {
5257 Some((payload, control_handle))
5258 } else {
5259 None
5260 }
5261 }
5262
5263 #[allow(irrefutable_let_patterns)]
5264 pub fn into_set_debug_client_info(
5265 self,
5266 ) -> Option<(NodeSetDebugClientInfoRequest, BufferCollectionControlHandle)> {
5267 if let BufferCollectionRequest::SetDebugClientInfo { payload, control_handle } = self {
5268 Some((payload, control_handle))
5269 } else {
5270 None
5271 }
5272 }
5273
5274 #[allow(irrefutable_let_patterns)]
5275 pub fn into_set_debug_timeout_log_deadline(
5276 self,
5277 ) -> Option<(NodeSetDebugTimeoutLogDeadlineRequest, BufferCollectionControlHandle)> {
5278 if let BufferCollectionRequest::SetDebugTimeoutLogDeadline { payload, control_handle } =
5279 self
5280 {
5281 Some((payload, control_handle))
5282 } else {
5283 None
5284 }
5285 }
5286
5287 #[allow(irrefutable_let_patterns)]
5288 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionControlHandle)> {
5289 if let BufferCollectionRequest::SetVerboseLogging { control_handle } = self {
5290 Some((control_handle))
5291 } else {
5292 None
5293 }
5294 }
5295
5296 #[allow(irrefutable_let_patterns)]
5297 pub fn into_get_node_ref(self) -> Option<(BufferCollectionGetNodeRefResponder)> {
5298 if let BufferCollectionRequest::GetNodeRef { responder } = self {
5299 Some((responder))
5300 } else {
5301 None
5302 }
5303 }
5304
5305 #[allow(irrefutable_let_patterns)]
5306 pub fn into_is_alternate_for(
5307 self,
5308 ) -> Option<(NodeIsAlternateForRequest, BufferCollectionIsAlternateForResponder)> {
5309 if let BufferCollectionRequest::IsAlternateFor { payload, responder } = self {
5310 Some((payload, responder))
5311 } else {
5312 None
5313 }
5314 }
5315
5316 #[allow(irrefutable_let_patterns)]
5317 pub fn into_get_buffer_collection_id(
5318 self,
5319 ) -> Option<(BufferCollectionGetBufferCollectionIdResponder)> {
5320 if let BufferCollectionRequest::GetBufferCollectionId { responder } = self {
5321 Some((responder))
5322 } else {
5323 None
5324 }
5325 }
5326
5327 #[allow(irrefutable_let_patterns)]
5328 pub fn into_set_weak(self) -> Option<(BufferCollectionControlHandle)> {
5329 if let BufferCollectionRequest::SetWeak { control_handle } = self {
5330 Some((control_handle))
5331 } else {
5332 None
5333 }
5334 }
5335
5336 #[allow(irrefutable_let_patterns)]
5337 pub fn into_set_weak_ok(self) -> Option<(NodeSetWeakOkRequest, BufferCollectionControlHandle)> {
5338 if let BufferCollectionRequest::SetWeakOk { payload, control_handle } = self {
5339 Some((payload, control_handle))
5340 } else {
5341 None
5342 }
5343 }
5344
5345 #[allow(irrefutable_let_patterns)]
5346 pub fn into_attach_node_tracking(
5347 self,
5348 ) -> Option<(NodeAttachNodeTrackingRequest, BufferCollectionControlHandle)> {
5349 if let BufferCollectionRequest::AttachNodeTracking { payload, control_handle } = self {
5350 Some((payload, control_handle))
5351 } else {
5352 None
5353 }
5354 }
5355
5356 #[allow(irrefutable_let_patterns)]
5357 pub fn into_set_constraints(
5358 self,
5359 ) -> Option<(BufferCollectionSetConstraintsRequest, BufferCollectionControlHandle)> {
5360 if let BufferCollectionRequest::SetConstraints { payload, control_handle } = self {
5361 Some((payload, control_handle))
5362 } else {
5363 None
5364 }
5365 }
5366
5367 #[allow(irrefutable_let_patterns)]
5368 pub fn into_wait_for_all_buffers_allocated(
5369 self,
5370 ) -> Option<(BufferCollectionWaitForAllBuffersAllocatedResponder)> {
5371 if let BufferCollectionRequest::WaitForAllBuffersAllocated { responder } = self {
5372 Some((responder))
5373 } else {
5374 None
5375 }
5376 }
5377
5378 #[allow(irrefutable_let_patterns)]
5379 pub fn into_check_all_buffers_allocated(
5380 self,
5381 ) -> Option<(BufferCollectionCheckAllBuffersAllocatedResponder)> {
5382 if let BufferCollectionRequest::CheckAllBuffersAllocated { responder } = self {
5383 Some((responder))
5384 } else {
5385 None
5386 }
5387 }
5388
5389 #[allow(irrefutable_let_patterns)]
5390 pub fn into_attach_token(
5391 self,
5392 ) -> Option<(BufferCollectionAttachTokenRequest, BufferCollectionControlHandle)> {
5393 if let BufferCollectionRequest::AttachToken { payload, control_handle } = self {
5394 Some((payload, control_handle))
5395 } else {
5396 None
5397 }
5398 }
5399
5400 #[allow(irrefutable_let_patterns)]
5401 pub fn into_attach_lifetime_tracking(
5402 self,
5403 ) -> Option<(BufferCollectionAttachLifetimeTrackingRequest, BufferCollectionControlHandle)>
5404 {
5405 if let BufferCollectionRequest::AttachLifetimeTracking { payload, control_handle } = self {
5406 Some((payload, control_handle))
5407 } else {
5408 None
5409 }
5410 }
5411
5412 /// Name of the method defined in FIDL
5413 pub fn method_name(&self) -> &'static str {
5414 match *self {
5415 BufferCollectionRequest::Sync { .. } => "sync",
5416 BufferCollectionRequest::Release { .. } => "release",
5417 BufferCollectionRequest::SetName { .. } => "set_name",
5418 BufferCollectionRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
5419 BufferCollectionRequest::SetDebugTimeoutLogDeadline { .. } => {
5420 "set_debug_timeout_log_deadline"
5421 }
5422 BufferCollectionRequest::SetVerboseLogging { .. } => "set_verbose_logging",
5423 BufferCollectionRequest::GetNodeRef { .. } => "get_node_ref",
5424 BufferCollectionRequest::IsAlternateFor { .. } => "is_alternate_for",
5425 BufferCollectionRequest::GetBufferCollectionId { .. } => "get_buffer_collection_id",
5426 BufferCollectionRequest::SetWeak { .. } => "set_weak",
5427 BufferCollectionRequest::SetWeakOk { .. } => "set_weak_ok",
5428 BufferCollectionRequest::AttachNodeTracking { .. } => "attach_node_tracking",
5429 BufferCollectionRequest::SetConstraints { .. } => "set_constraints",
5430 BufferCollectionRequest::WaitForAllBuffersAllocated { .. } => {
5431 "wait_for_all_buffers_allocated"
5432 }
5433 BufferCollectionRequest::CheckAllBuffersAllocated { .. } => {
5434 "check_all_buffers_allocated"
5435 }
5436 BufferCollectionRequest::AttachToken { .. } => "attach_token",
5437 BufferCollectionRequest::AttachLifetimeTracking { .. } => "attach_lifetime_tracking",
5438 BufferCollectionRequest::_UnknownMethod {
5439 method_type: fidl::MethodType::OneWay,
5440 ..
5441 } => "unknown one-way method",
5442 BufferCollectionRequest::_UnknownMethod {
5443 method_type: fidl::MethodType::TwoWay,
5444 ..
5445 } => "unknown two-way method",
5446 }
5447 }
5448}
5449
5450#[derive(Debug, Clone)]
5451pub struct BufferCollectionControlHandle {
5452 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
5453}
5454
5455impl BufferCollectionControlHandle {
5456 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
5457 self.inner.shutdown_with_epitaph(status.into())
5458 }
5459}
5460
5461impl fidl::endpoints::ControlHandle for BufferCollectionControlHandle {
5462 fn shutdown(&self) {
5463 self.inner.shutdown()
5464 }
5465
5466 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
5467 self.inner.shutdown_with_epitaph(status)
5468 }
5469
5470 fn is_closed(&self) -> bool {
5471 self.inner.channel().is_closed()
5472 }
5473 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
5474 self.inner.channel().on_closed()
5475 }
5476
5477 #[cfg(target_os = "fuchsia")]
5478 fn signal_peer(
5479 &self,
5480 clear_mask: zx::Signals,
5481 set_mask: zx::Signals,
5482 ) -> Result<(), zx_status::Status> {
5483 use fidl::Peered;
5484 self.inner.channel().signal_peer(clear_mask, set_mask)
5485 }
5486}
5487
5488impl BufferCollectionControlHandle {}
5489
5490#[must_use = "FIDL methods require a response to be sent"]
5491#[derive(Debug)]
5492pub struct BufferCollectionSyncResponder {
5493 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5494 tx_id: u32,
5495}
5496
5497/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5498/// if the responder is dropped without sending a response, so that the client
5499/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5500impl std::ops::Drop for BufferCollectionSyncResponder {
5501 fn drop(&mut self) {
5502 self.control_handle.shutdown();
5503 // Safety: drops once, never accessed again
5504 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5505 }
5506}
5507
5508impl fidl::endpoints::Responder for BufferCollectionSyncResponder {
5509 type ControlHandle = BufferCollectionControlHandle;
5510
5511 fn control_handle(&self) -> &BufferCollectionControlHandle {
5512 &self.control_handle
5513 }
5514
5515 fn drop_without_shutdown(mut self) {
5516 // Safety: drops once, never accessed again due to mem::forget
5517 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5518 // Prevent Drop from running (which would shut down the channel)
5519 std::mem::forget(self);
5520 }
5521}
5522
5523impl BufferCollectionSyncResponder {
5524 /// Sends a response to the FIDL transaction.
5525 ///
5526 /// Sets the channel to shutdown if an error occurs.
5527 pub fn send(self) -> Result<(), fidl::Error> {
5528 let _result = self.send_raw();
5529 if _result.is_err() {
5530 self.control_handle.shutdown();
5531 }
5532 self.drop_without_shutdown();
5533 _result
5534 }
5535
5536 /// Similar to "send" but does not shutdown the channel if an error occurs.
5537 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
5538 let _result = self.send_raw();
5539 self.drop_without_shutdown();
5540 _result
5541 }
5542
5543 fn send_raw(&self) -> Result<(), fidl::Error> {
5544 self.control_handle.inner.send::<fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>>(
5545 fidl::encoding::Flexible::new(()),
5546 self.tx_id,
5547 0x11ac2555cf575b54,
5548 fidl::encoding::DynamicFlags::FLEXIBLE,
5549 )
5550 }
5551}
5552
5553#[must_use = "FIDL methods require a response to be sent"]
5554#[derive(Debug)]
5555pub struct BufferCollectionGetNodeRefResponder {
5556 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5557 tx_id: u32,
5558}
5559
5560/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5561/// if the responder is dropped without sending a response, so that the client
5562/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5563impl std::ops::Drop for BufferCollectionGetNodeRefResponder {
5564 fn drop(&mut self) {
5565 self.control_handle.shutdown();
5566 // Safety: drops once, never accessed again
5567 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5568 }
5569}
5570
5571impl fidl::endpoints::Responder for BufferCollectionGetNodeRefResponder {
5572 type ControlHandle = BufferCollectionControlHandle;
5573
5574 fn control_handle(&self) -> &BufferCollectionControlHandle {
5575 &self.control_handle
5576 }
5577
5578 fn drop_without_shutdown(mut self) {
5579 // Safety: drops once, never accessed again due to mem::forget
5580 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5581 // Prevent Drop from running (which would shut down the channel)
5582 std::mem::forget(self);
5583 }
5584}
5585
5586impl BufferCollectionGetNodeRefResponder {
5587 /// Sends a response to the FIDL transaction.
5588 ///
5589 /// Sets the channel to shutdown if an error occurs.
5590 pub fn send(self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
5591 let _result = self.send_raw(payload);
5592 if _result.is_err() {
5593 self.control_handle.shutdown();
5594 }
5595 self.drop_without_shutdown();
5596 _result
5597 }
5598
5599 /// Similar to "send" but does not shutdown the channel if an error occurs.
5600 pub fn send_no_shutdown_on_err(
5601 self,
5602 mut payload: NodeGetNodeRefResponse,
5603 ) -> Result<(), fidl::Error> {
5604 let _result = self.send_raw(payload);
5605 self.drop_without_shutdown();
5606 _result
5607 }
5608
5609 fn send_raw(&self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
5610 self.control_handle.inner.send::<fidl::encoding::FlexibleType<NodeGetNodeRefResponse>>(
5611 fidl::encoding::Flexible::new(&mut payload),
5612 self.tx_id,
5613 0x5b3d0e51614df053,
5614 fidl::encoding::DynamicFlags::FLEXIBLE,
5615 )
5616 }
5617}
5618
5619#[must_use = "FIDL methods require a response to be sent"]
5620#[derive(Debug)]
5621pub struct BufferCollectionIsAlternateForResponder {
5622 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5623 tx_id: u32,
5624}
5625
5626/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5627/// if the responder is dropped without sending a response, so that the client
5628/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5629impl std::ops::Drop for BufferCollectionIsAlternateForResponder {
5630 fn drop(&mut self) {
5631 self.control_handle.shutdown();
5632 // Safety: drops once, never accessed again
5633 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5634 }
5635}
5636
5637impl fidl::endpoints::Responder for BufferCollectionIsAlternateForResponder {
5638 type ControlHandle = BufferCollectionControlHandle;
5639
5640 fn control_handle(&self) -> &BufferCollectionControlHandle {
5641 &self.control_handle
5642 }
5643
5644 fn drop_without_shutdown(mut self) {
5645 // Safety: drops once, never accessed again due to mem::forget
5646 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5647 // Prevent Drop from running (which would shut down the channel)
5648 std::mem::forget(self);
5649 }
5650}
5651
5652impl BufferCollectionIsAlternateForResponder {
5653 /// Sends a response to the FIDL transaction.
5654 ///
5655 /// Sets the channel to shutdown if an error occurs.
5656 pub fn send(
5657 self,
5658 mut result: Result<&NodeIsAlternateForResponse, Error>,
5659 ) -> Result<(), fidl::Error> {
5660 let _result = self.send_raw(result);
5661 if _result.is_err() {
5662 self.control_handle.shutdown();
5663 }
5664 self.drop_without_shutdown();
5665 _result
5666 }
5667
5668 /// Similar to "send" but does not shutdown the channel if an error occurs.
5669 pub fn send_no_shutdown_on_err(
5670 self,
5671 mut result: Result<&NodeIsAlternateForResponse, Error>,
5672 ) -> Result<(), fidl::Error> {
5673 let _result = self.send_raw(result);
5674 self.drop_without_shutdown();
5675 _result
5676 }
5677
5678 fn send_raw(
5679 &self,
5680 mut result: Result<&NodeIsAlternateForResponse, Error>,
5681 ) -> Result<(), fidl::Error> {
5682 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
5683 NodeIsAlternateForResponse,
5684 Error,
5685 >>(
5686 fidl::encoding::FlexibleResult::new(result),
5687 self.tx_id,
5688 0x3a58e00157e0825,
5689 fidl::encoding::DynamicFlags::FLEXIBLE,
5690 )
5691 }
5692}
5693
5694#[must_use = "FIDL methods require a response to be sent"]
5695#[derive(Debug)]
5696pub struct BufferCollectionGetBufferCollectionIdResponder {
5697 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5698 tx_id: u32,
5699}
5700
5701/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5702/// if the responder is dropped without sending a response, so that the client
5703/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5704impl std::ops::Drop for BufferCollectionGetBufferCollectionIdResponder {
5705 fn drop(&mut self) {
5706 self.control_handle.shutdown();
5707 // Safety: drops once, never accessed again
5708 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5709 }
5710}
5711
5712impl fidl::endpoints::Responder for BufferCollectionGetBufferCollectionIdResponder {
5713 type ControlHandle = BufferCollectionControlHandle;
5714
5715 fn control_handle(&self) -> &BufferCollectionControlHandle {
5716 &self.control_handle
5717 }
5718
5719 fn drop_without_shutdown(mut self) {
5720 // Safety: drops once, never accessed again due to mem::forget
5721 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5722 // Prevent Drop from running (which would shut down the channel)
5723 std::mem::forget(self);
5724 }
5725}
5726
5727impl BufferCollectionGetBufferCollectionIdResponder {
5728 /// Sends a response to the FIDL transaction.
5729 ///
5730 /// Sets the channel to shutdown if an error occurs.
5731 pub fn send(self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
5732 let _result = self.send_raw(payload);
5733 if _result.is_err() {
5734 self.control_handle.shutdown();
5735 }
5736 self.drop_without_shutdown();
5737 _result
5738 }
5739
5740 /// Similar to "send" but does not shutdown the channel if an error occurs.
5741 pub fn send_no_shutdown_on_err(
5742 self,
5743 mut payload: &NodeGetBufferCollectionIdResponse,
5744 ) -> Result<(), fidl::Error> {
5745 let _result = self.send_raw(payload);
5746 self.drop_without_shutdown();
5747 _result
5748 }
5749
5750 fn send_raw(&self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
5751 self.control_handle
5752 .inner
5753 .send::<fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>>(
5754 fidl::encoding::Flexible::new(payload),
5755 self.tx_id,
5756 0x77d19a494b78ba8c,
5757 fidl::encoding::DynamicFlags::FLEXIBLE,
5758 )
5759 }
5760}
5761
5762#[must_use = "FIDL methods require a response to be sent"]
5763#[derive(Debug)]
5764pub struct BufferCollectionWaitForAllBuffersAllocatedResponder {
5765 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5766 tx_id: u32,
5767}
5768
5769/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5770/// if the responder is dropped without sending a response, so that the client
5771/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5772impl std::ops::Drop for BufferCollectionWaitForAllBuffersAllocatedResponder {
5773 fn drop(&mut self) {
5774 self.control_handle.shutdown();
5775 // Safety: drops once, never accessed again
5776 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5777 }
5778}
5779
5780impl fidl::endpoints::Responder for BufferCollectionWaitForAllBuffersAllocatedResponder {
5781 type ControlHandle = BufferCollectionControlHandle;
5782
5783 fn control_handle(&self) -> &BufferCollectionControlHandle {
5784 &self.control_handle
5785 }
5786
5787 fn drop_without_shutdown(mut self) {
5788 // Safety: drops once, never accessed again due to mem::forget
5789 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5790 // Prevent Drop from running (which would shut down the channel)
5791 std::mem::forget(self);
5792 }
5793}
5794
5795impl BufferCollectionWaitForAllBuffersAllocatedResponder {
5796 /// Sends a response to the FIDL transaction.
5797 ///
5798 /// Sets the channel to shutdown if an error occurs.
5799 pub fn send(
5800 self,
5801 mut result: Result<BufferCollectionWaitForAllBuffersAllocatedResponse, Error>,
5802 ) -> Result<(), fidl::Error> {
5803 let _result = self.send_raw(result);
5804 if _result.is_err() {
5805 self.control_handle.shutdown();
5806 }
5807 self.drop_without_shutdown();
5808 _result
5809 }
5810
5811 /// Similar to "send" but does not shutdown the channel if an error occurs.
5812 pub fn send_no_shutdown_on_err(
5813 self,
5814 mut result: Result<BufferCollectionWaitForAllBuffersAllocatedResponse, Error>,
5815 ) -> Result<(), fidl::Error> {
5816 let _result = self.send_raw(result);
5817 self.drop_without_shutdown();
5818 _result
5819 }
5820
5821 fn send_raw(
5822 &self,
5823 mut result: Result<BufferCollectionWaitForAllBuffersAllocatedResponse, Error>,
5824 ) -> Result<(), fidl::Error> {
5825 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
5826 BufferCollectionWaitForAllBuffersAllocatedResponse,
5827 Error,
5828 >>(
5829 fidl::encoding::FlexibleResult::new(result.as_mut().map_err(|e| *e)),
5830 self.tx_id,
5831 0x62300344b61404e,
5832 fidl::encoding::DynamicFlags::FLEXIBLE,
5833 )
5834 }
5835}
5836
5837#[must_use = "FIDL methods require a response to be sent"]
5838#[derive(Debug)]
5839pub struct BufferCollectionCheckAllBuffersAllocatedResponder {
5840 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5841 tx_id: u32,
5842}
5843
5844/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5845/// if the responder is dropped without sending a response, so that the client
5846/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5847impl std::ops::Drop for BufferCollectionCheckAllBuffersAllocatedResponder {
5848 fn drop(&mut self) {
5849 self.control_handle.shutdown();
5850 // Safety: drops once, never accessed again
5851 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5852 }
5853}
5854
5855impl fidl::endpoints::Responder for BufferCollectionCheckAllBuffersAllocatedResponder {
5856 type ControlHandle = BufferCollectionControlHandle;
5857
5858 fn control_handle(&self) -> &BufferCollectionControlHandle {
5859 &self.control_handle
5860 }
5861
5862 fn drop_without_shutdown(mut self) {
5863 // Safety: drops once, never accessed again due to mem::forget
5864 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5865 // Prevent Drop from running (which would shut down the channel)
5866 std::mem::forget(self);
5867 }
5868}
5869
5870impl BufferCollectionCheckAllBuffersAllocatedResponder {
5871 /// Sends a response to the FIDL transaction.
5872 ///
5873 /// Sets the channel to shutdown if an error occurs.
5874 pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
5875 let _result = self.send_raw(result);
5876 if _result.is_err() {
5877 self.control_handle.shutdown();
5878 }
5879 self.drop_without_shutdown();
5880 _result
5881 }
5882
5883 /// Similar to "send" but does not shutdown the channel if an error occurs.
5884 pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
5885 let _result = self.send_raw(result);
5886 self.drop_without_shutdown();
5887 _result
5888 }
5889
5890 fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
5891 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
5892 fidl::encoding::EmptyStruct,
5893 Error,
5894 >>(
5895 fidl::encoding::FlexibleResult::new(result),
5896 self.tx_id,
5897 0x35a5fe77ce939c10,
5898 fidl::encoding::DynamicFlags::FLEXIBLE,
5899 )
5900 }
5901}
5902
5903#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
5904pub struct BufferCollectionTokenMarker;
5905
5906impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenMarker {
5907 type Proxy = BufferCollectionTokenProxy;
5908 type RequestStream = BufferCollectionTokenRequestStream;
5909 #[cfg(target_os = "fuchsia")]
5910 type SynchronousProxy = BufferCollectionTokenSynchronousProxy;
5911
5912 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionToken";
5913}
5914
5915pub trait BufferCollectionTokenProxyInterface: Send + Sync {
5916 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
5917 fn r#sync(&self) -> Self::SyncResponseFut;
5918 fn r#release(&self) -> Result<(), fidl::Error>;
5919 fn r#set_name(&self, payload: &NodeSetNameRequest) -> Result<(), fidl::Error>;
5920 fn r#set_debug_client_info(
5921 &self,
5922 payload: &NodeSetDebugClientInfoRequest,
5923 ) -> Result<(), fidl::Error>;
5924 fn r#set_debug_timeout_log_deadline(
5925 &self,
5926 payload: &NodeSetDebugTimeoutLogDeadlineRequest,
5927 ) -> Result<(), fidl::Error>;
5928 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
5929 type GetNodeRefResponseFut: std::future::Future<Output = Result<NodeGetNodeRefResponse, fidl::Error>>
5930 + Send;
5931 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
5932 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
5933 + Send;
5934 fn r#is_alternate_for(
5935 &self,
5936 payload: NodeIsAlternateForRequest,
5937 ) -> Self::IsAlternateForResponseFut;
5938 type GetBufferCollectionIdResponseFut: std::future::Future<Output = Result<NodeGetBufferCollectionIdResponse, fidl::Error>>
5939 + Send;
5940 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut;
5941 fn r#set_weak(&self) -> Result<(), fidl::Error>;
5942 fn r#set_weak_ok(&self, payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error>;
5943 fn r#attach_node_tracking(
5944 &self,
5945 payload: NodeAttachNodeTrackingRequest,
5946 ) -> Result<(), fidl::Error>;
5947 type DuplicateSyncResponseFut: std::future::Future<
5948 Output = Result<BufferCollectionTokenDuplicateSyncResponse, fidl::Error>,
5949 > + Send;
5950 fn r#duplicate_sync(
5951 &self,
5952 payload: &BufferCollectionTokenDuplicateSyncRequest,
5953 ) -> Self::DuplicateSyncResponseFut;
5954 fn r#duplicate(
5955 &self,
5956 payload: BufferCollectionTokenDuplicateRequest,
5957 ) -> Result<(), fidl::Error>;
5958 fn r#set_dispensable(&self) -> Result<(), fidl::Error>;
5959 fn r#create_buffer_collection_token_group(
5960 &self,
5961 payload: BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
5962 ) -> Result<(), fidl::Error>;
5963}
5964#[derive(Debug)]
5965#[cfg(target_os = "fuchsia")]
5966pub struct BufferCollectionTokenSynchronousProxy {
5967 client: fidl::client::sync::Client,
5968}
5969
5970#[cfg(target_os = "fuchsia")]
5971impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenSynchronousProxy {
5972 type Proxy = BufferCollectionTokenProxy;
5973 type Protocol = BufferCollectionTokenMarker;
5974
5975 fn from_channel(inner: fidl::Channel) -> Self {
5976 Self::new(inner)
5977 }
5978
5979 fn into_channel(self) -> fidl::Channel {
5980 self.client.into_channel()
5981 }
5982
5983 fn as_channel(&self) -> &fidl::Channel {
5984 self.client.as_channel()
5985 }
5986}
5987
5988#[cfg(target_os = "fuchsia")]
5989impl BufferCollectionTokenSynchronousProxy {
5990 pub fn new(channel: fidl::Channel) -> Self {
5991 Self { client: fidl::client::sync::Client::new(channel) }
5992 }
5993
5994 pub fn into_channel(self) -> fidl::Channel {
5995 self.client.into_channel()
5996 }
5997
5998 /// Waits until an event arrives and returns it. It is safe for other
5999 /// threads to make concurrent requests while waiting for an event.
6000 pub fn wait_for_event(
6001 &self,
6002 deadline: zx::MonotonicInstant,
6003 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
6004 BufferCollectionTokenEvent::decode(
6005 self.client.wait_for_event::<BufferCollectionTokenMarker>(deadline)?,
6006 )
6007 }
6008
6009 /// Ensure that previous messages have been received server side. This is
6010 /// particularly useful after previous messages that created new tokens,
6011 /// because a token must be known to the sysmem server before sending the
6012 /// token to another participant.
6013 ///
6014 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
6015 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
6016 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
6017 /// to mitigate the possibility of a hostile/fake
6018 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
6019 /// Another way is to pass the token to
6020 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
6021 /// the token as part of exchanging it for a
6022 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
6023 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
6024 /// of stalling.
6025 ///
6026 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
6027 /// and then starting and completing a `Sync`, it's then safe to send the
6028 /// `BufferCollectionToken` client ends to other participants knowing the
6029 /// server will recognize the tokens when they're sent by the other
6030 /// participants to sysmem in a
6031 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
6032 /// efficient way to create tokens while avoiding unnecessary round trips.
6033 ///
6034 /// Other options include waiting for each
6035 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
6036 /// individually (using separate call to `Sync` after each), or calling
6037 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
6038 /// converted to a `BufferCollection` via
6039 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
6040 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
6041 /// the sync step and can create multiple tokens at once.
6042 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
6043 let _response = self.client.send_query::<
6044 fidl::encoding::EmptyPayload,
6045 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
6046 BufferCollectionTokenMarker,
6047 >(
6048 (),
6049 0x11ac2555cf575b54,
6050 fidl::encoding::DynamicFlags::FLEXIBLE,
6051 ___deadline,
6052 )?
6053 .into_result::<BufferCollectionTokenMarker>("sync")?;
6054 Ok(_response)
6055 }
6056
6057 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
6058 ///
6059 /// Normally a participant will convert a `BufferCollectionToken` into a
6060 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
6061 /// `Release` via the token (and then close the channel immediately or
6062 /// shortly later in response to server closing the server end), which
6063 /// avoids causing buffer collection failure. Without a prior `Release`,
6064 /// closing the `BufferCollectionToken` client end will cause buffer
6065 /// collection failure.
6066 ///
6067 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
6068 ///
6069 /// By default the server handles unexpected closure of a
6070 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
6071 /// first) by failing the buffer collection. Partly this is to expedite
6072 /// closing VMO handles to reclaim memory when any participant fails. If a
6073 /// participant would like to cleanly close a `BufferCollection` without
6074 /// causing buffer collection failure, the participant can send `Release`
6075 /// before closing the `BufferCollection` client end. The `Release` can
6076 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
6077 /// buffer collection won't require constraints from this node in order to
6078 /// allocate. If after `SetConstraints`, the constraints are retained and
6079 /// aggregated, despite the lack of `BufferCollection` connection at the
6080 /// time of constraints aggregation.
6081 ///
6082 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
6083 ///
6084 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
6085 /// end (without `Release` first) will trigger failure of the buffer
6086 /// collection. To close a `BufferCollectionTokenGroup` channel without
6087 /// failing the buffer collection, ensure that AllChildrenPresent() has been
6088 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
6089 /// client end.
6090 ///
6091 /// If `Release` occurs before
6092 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
6093 /// buffer collection will fail (triggered by reception of `Release` without
6094 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
6095 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
6096 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
6097 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
6098 /// close requires `AllChildrenPresent` (if not already sent), then
6099 /// `Release`, then close client end.
6100 ///
6101 /// If `Release` occurs after `AllChildrenPresent`, the children and all
6102 /// their constraints remain intact (just as they would if the
6103 /// `BufferCollectionTokenGroup` channel had remained open), and the client
6104 /// end close doesn't trigger buffer collection failure.
6105 ///
6106 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
6107 ///
6108 /// For brevity, the per-channel-protocol paragraphs above ignore the
6109 /// separate failure domain created by
6110 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
6111 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
6112 /// unexpectedly closes (without `Release` first) and that client end is
6113 /// under a failure domain, instead of failing the whole buffer collection,
6114 /// the failure domain is failed, but the buffer collection itself is
6115 /// isolated from failure of the failure domain. Such failure domains can be
6116 /// nested, in which case only the inner-most failure domain in which the
6117 /// `Node` resides fails.
6118 pub fn r#release(&self) -> Result<(), fidl::Error> {
6119 self.client.send::<fidl::encoding::EmptyPayload>(
6120 (),
6121 0x6a5cae7d6d6e04c6,
6122 fidl::encoding::DynamicFlags::FLEXIBLE,
6123 )
6124 }
6125
6126 /// Set a name for VMOs in this buffer collection.
6127 ///
6128 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
6129 /// will be truncated to fit. The name of the vmo will be suffixed with the
6130 /// buffer index within the collection (if the suffix fits within
6131 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
6132 /// listed in the inspect data.
6133 ///
6134 /// The name only affects VMOs allocated after the name is set; this call
6135 /// does not rename existing VMOs. If multiple clients set different names
6136 /// then the larger priority value will win. Setting a new name with the
6137 /// same priority as a prior name doesn't change the name.
6138 ///
6139 /// All table fields are currently required.
6140 ///
6141 /// + request `priority` The name is only set if this is the first `SetName`
6142 /// or if `priority` is greater than any previous `priority` value in
6143 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
6144 /// + request `name` The name for VMOs created under this buffer collection.
6145 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
6146 self.client.send::<NodeSetNameRequest>(
6147 payload,
6148 0xb41f1624f48c1e9,
6149 fidl::encoding::DynamicFlags::FLEXIBLE,
6150 )
6151 }
6152
6153 /// Set information about the current client that can be used by sysmem to
6154 /// help diagnose leaking memory and allocation stalls waiting for a
6155 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
6156 ///
6157 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
6158 /// `Node`(s) derived from this `Node`, unless overriden by
6159 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
6160 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
6161 ///
6162 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
6163 /// `Allocator` is the most efficient way to ensure that all
6164 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
6165 /// set, and is also more efficient than separately sending the same debug
6166 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
6167 /// created [`fuchsia.sysmem2/Node`].
6168 ///
6169 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
6170 /// indicate which client is closing their channel first, leading to subtree
6171 /// failure (which can be normal if the purpose of the subtree is over, but
6172 /// if happening earlier than expected, the client-channel-specific name can
6173 /// help diagnose where the failure is first coming from, from sysmem's
6174 /// point of view).
6175 ///
6176 /// All table fields are currently required.
6177 ///
6178 /// + request `name` This can be an arbitrary string, but the current
6179 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
6180 /// + request `id` This can be an arbitrary id, but the current process ID
6181 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
6182 pub fn r#set_debug_client_info(
6183 &self,
6184 mut payload: &NodeSetDebugClientInfoRequest,
6185 ) -> Result<(), fidl::Error> {
6186 self.client.send::<NodeSetDebugClientInfoRequest>(
6187 payload,
6188 0x5cde8914608d99b1,
6189 fidl::encoding::DynamicFlags::FLEXIBLE,
6190 )
6191 }
6192
6193 /// Sysmem logs a warning if sysmem hasn't seen
6194 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
6195 /// within 5 seconds after creation of a new collection.
6196 ///
6197 /// Clients can call this method to change when the log is printed. If
6198 /// multiple client set the deadline, it's unspecified which deadline will
6199 /// take effect.
6200 ///
6201 /// In most cases the default works well.
6202 ///
6203 /// All table fields are currently required.
6204 ///
6205 /// + request `deadline` The time at which sysmem will start trying to log
6206 /// the warning, unless all constraints are with sysmem by then.
6207 pub fn r#set_debug_timeout_log_deadline(
6208 &self,
6209 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
6210 ) -> Result<(), fidl::Error> {
6211 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
6212 payload,
6213 0x716b0af13d5c0806,
6214 fidl::encoding::DynamicFlags::FLEXIBLE,
6215 )
6216 }
6217
6218 /// This enables verbose logging for the buffer collection.
6219 ///
6220 /// Verbose logging includes constraints set via
6221 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
6222 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
6223 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
6224 /// the tree of `Node`(s).
6225 ///
6226 /// Normally sysmem prints only a single line complaint when aggregation
6227 /// fails, with just the specific detailed reason that aggregation failed,
6228 /// with little surrounding context. While this is often enough to diagnose
6229 /// a problem if only a small change was made and everything was working
6230 /// before the small change, it's often not particularly helpful for getting
6231 /// a new buffer collection to work for the first time. Especially with
6232 /// more complex trees of nodes, involving things like
6233 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
6234 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
6235 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
6236 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
6237 /// looks like and why it's failing a logical allocation, or why a tree or
6238 /// subtree is failing sooner than expected.
6239 ///
6240 /// The intent of the extra logging is to be acceptable from a performance
6241 /// point of view, under the assumption that verbose logging is only enabled
6242 /// on a low number of buffer collections. If we're not tracking down a bug,
6243 /// we shouldn't send this message.
6244 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
6245 self.client.send::<fidl::encoding::EmptyPayload>(
6246 (),
6247 0x5209c77415b4dfad,
6248 fidl::encoding::DynamicFlags::FLEXIBLE,
6249 )
6250 }
6251
6252 /// This gets a handle that can be used as a parameter to
6253 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
6254 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
6255 /// client obtained this handle from this `Node`.
6256 ///
6257 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
6258 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
6259 /// despite the two calls typically being on different channels.
6260 ///
6261 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
6262 ///
6263 /// All table fields are currently required.
6264 ///
6265 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
6266 /// different `Node` channel, to prove that the client obtained the handle
6267 /// from this `Node`.
6268 pub fn r#get_node_ref(
6269 &self,
6270 ___deadline: zx::MonotonicInstant,
6271 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
6272 let _response = self.client.send_query::<
6273 fidl::encoding::EmptyPayload,
6274 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
6275 BufferCollectionTokenMarker,
6276 >(
6277 (),
6278 0x5b3d0e51614df053,
6279 fidl::encoding::DynamicFlags::FLEXIBLE,
6280 ___deadline,
6281 )?
6282 .into_result::<BufferCollectionTokenMarker>("get_node_ref")?;
6283 Ok(_response)
6284 }
6285
6286 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
6287 /// rooted at a different child token of a common parent
6288 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
6289 /// passed-in `node_ref`.
6290 ///
6291 /// This call is for assisting with admission control de-duplication, and
6292 /// with debugging.
6293 ///
6294 /// The `node_ref` must be obtained using
6295 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
6296 ///
6297 /// The `node_ref` can be a duplicated handle; it's not necessary to call
6298 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
6299 ///
6300 /// If a calling token may not actually be a valid token at all due to a
6301 /// potentially hostile/untrusted provider of the token, call
6302 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
6303 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
6304 /// never responds due to a calling token not being a real token (not really
6305 /// talking to sysmem). Another option is to call
6306 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
6307 /// which also validates the token along with converting it to a
6308 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
6309 ///
6310 /// All table fields are currently required.
6311 ///
6312 /// - response `is_alternate`
6313 /// - true: The first parent node in common between the calling node and
6314 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
6315 /// that the calling `Node` and the `node_ref` `Node` will not have both
6316 /// their constraints apply - rather sysmem will choose one or the other
6317 /// of the constraints - never both. This is because only one child of
6318 /// a `BufferCollectionTokenGroup` is selected during logical
6319 /// allocation, with only that one child's subtree contributing to
6320 /// constraints aggregation.
6321 /// - false: The first parent node in common between the calling `Node`
6322 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
6323 /// Currently, this means the first parent node in common is a
6324 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
6325 /// `Release`ed). This means that the calling `Node` and the `node_ref`
6326 /// `Node` may have both their constraints apply during constraints
6327 /// aggregation of the logical allocation, if both `Node`(s) are
6328 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
6329 /// this case, there is no `BufferCollectionTokenGroup` that will
6330 /// directly prevent the two `Node`(s) from both being selected and
6331 /// their constraints both aggregated, but even when false, one or both
6332 /// `Node`(s) may still be eliminated from consideration if one or both
6333 /// `Node`(s) has a direct or indirect parent
6334 /// `BufferCollectionTokenGroup` which selects a child subtree other
6335 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
6336 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
6337 /// associated with the same buffer collection as the calling `Node`.
6338 /// Another reason for this error is if the `node_ref` is an
6339 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
6340 /// a real `node_ref` obtained from `GetNodeRef`.
6341 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
6342 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
6343 /// the needed rights expected on a real `node_ref`.
6344 /// * No other failing status codes are returned by this call. However,
6345 /// sysmem may add additional codes in future, so the client should have
6346 /// sensible default handling for any failing status code.
6347 pub fn r#is_alternate_for(
6348 &self,
6349 mut payload: NodeIsAlternateForRequest,
6350 ___deadline: zx::MonotonicInstant,
6351 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
6352 let _response = self.client.send_query::<
6353 NodeIsAlternateForRequest,
6354 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
6355 BufferCollectionTokenMarker,
6356 >(
6357 &mut payload,
6358 0x3a58e00157e0825,
6359 fidl::encoding::DynamicFlags::FLEXIBLE,
6360 ___deadline,
6361 )?
6362 .into_result::<BufferCollectionTokenMarker>("is_alternate_for")?;
6363 Ok(_response.map(|x| x))
6364 }
6365
6366 /// Get the buffer collection ID. This ID is also available from
6367 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
6368 /// within the collection).
6369 ///
6370 /// This call is mainly useful in situations where we can't convey a
6371 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
6372 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
6373 /// handle, which can be joined back up with a `BufferCollection` client end
6374 /// that was created via a different path. Prefer to convey a
6375 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
6376 ///
6377 /// Trusting a `buffer_collection_id` value from a source other than sysmem
6378 /// is analogous to trusting a koid value from a source other than zircon.
6379 /// Both should be avoided unless really necessary, and both require
6380 /// caution. In some situations it may be reasonable to refer to a
6381 /// pre-established `BufferCollection` by `buffer_collection_id` via a
6382 /// protocol for efficiency reasons, but an incoming value purporting to be
6383 /// a `buffer_collection_id` is not sufficient alone to justify granting the
6384 /// sender of the `buffer_collection_id` any capability. The sender must
6385 /// first prove to a receiver that the sender has/had a VMO or has/had a
6386 /// `BufferCollectionToken` to the same collection by sending a handle that
6387 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
6388 /// `buffer_collection_id` value. The receiver should take care to avoid
6389 /// assuming that a sender had a `BufferCollectionToken` in cases where the
6390 /// sender has only proven that the sender had a VMO.
6391 ///
6392 /// - response `buffer_collection_id` This ID is unique per buffer
6393 /// collection per boot. Each buffer is uniquely identified by the
6394 /// `buffer_collection_id` and `buffer_index` together.
6395 pub fn r#get_buffer_collection_id(
6396 &self,
6397 ___deadline: zx::MonotonicInstant,
6398 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
6399 let _response = self.client.send_query::<
6400 fidl::encoding::EmptyPayload,
6401 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
6402 BufferCollectionTokenMarker,
6403 >(
6404 (),
6405 0x77d19a494b78ba8c,
6406 fidl::encoding::DynamicFlags::FLEXIBLE,
6407 ___deadline,
6408 )?
6409 .into_result::<BufferCollectionTokenMarker>("get_buffer_collection_id")?;
6410 Ok(_response)
6411 }
6412
6413 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
6414 /// created after this message to weak, which means that a client's `Node`
6415 /// client end (or a child created after this message) is not alone
6416 /// sufficient to keep allocated VMOs alive.
6417 ///
6418 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
6419 /// `close_weak_asap`.
6420 ///
6421 /// This message is only permitted before the `Node` becomes ready for
6422 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
6423 /// * `BufferCollectionToken`: any time
6424 /// * `BufferCollection`: before `SetConstraints`
6425 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
6426 ///
6427 /// Currently, no conversion from strong `Node` to weak `Node` after ready
6428 /// for allocation is provided, but a client can simulate that by creating
6429 /// an additional `Node` before allocation and setting that additional
6430 /// `Node` to weak, and then potentially at some point later sending
6431 /// `Release` and closing the client end of the client's strong `Node`, but
6432 /// keeping the client's weak `Node`.
6433 ///
6434 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
6435 /// collection failure (all `Node` client end(s) will see
6436 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
6437 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
6438 /// this situation until all `Node`(s) are ready for allocation. For initial
6439 /// allocation to succeed, at least one strong `Node` is required to exist
6440 /// at allocation time, but after that client receives VMO handles, that
6441 /// client can `BufferCollection.Release` and close the client end without
6442 /// causing this type of failure.
6443 ///
6444 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
6445 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
6446 /// separately as appropriate.
6447 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
6448 self.client.send::<fidl::encoding::EmptyPayload>(
6449 (),
6450 0x22dd3ea514eeffe1,
6451 fidl::encoding::DynamicFlags::FLEXIBLE,
6452 )
6453 }
6454
6455 /// This indicates to sysmem that the client is prepared to pay attention to
6456 /// `close_weak_asap`.
6457 ///
6458 /// If sent, this message must be before
6459 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
6460 ///
6461 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
6462 /// send this message before `WaitForAllBuffersAllocated`, or a parent
6463 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
6464 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
6465 /// trigger buffer collection failure.
6466 ///
6467 /// This message is necessary because weak sysmem VMOs have not always been
6468 /// a thing, so older clients are not aware of the need to pay attention to
6469 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
6470 /// sysmem weak VMO handles asap. By having this message and requiring
6471 /// participants to indicate their acceptance of this aspect of the overall
6472 /// protocol, we avoid situations where an older client is delivered a weak
6473 /// VMO without any way for sysmem to get that VMO to close quickly later
6474 /// (and on a per-buffer basis).
6475 ///
6476 /// A participant that doesn't handle `close_weak_asap` and also doesn't
6477 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
6478 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
6479 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
6480 /// same participant has a child/delegate which does retrieve VMOs, that
6481 /// child/delegate will need to send `SetWeakOk` before
6482 /// `WaitForAllBuffersAllocated`.
6483 ///
6484 /// + request `for_child_nodes_also` If present and true, this means direct
6485 /// child nodes of this node created after this message plus all
6486 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
6487 /// those nodes. Any child node of this node that was created before this
6488 /// message is not included. This setting is "sticky" in the sense that a
6489 /// subsequent `SetWeakOk` without this bool set to true does not reset
6490 /// the server-side bool. If this creates a problem for a participant, a
6491 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
6492 /// tokens instead, as appropriate. A participant should only set
6493 /// `for_child_nodes_also` true if the participant can really promise to
6494 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
6495 /// weak VMO handles held by participants holding the corresponding child
6496 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
6497 /// which are using sysmem(1) can be weak, despite the clients of those
6498 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
6499 /// direct way to find out about `close_weak_asap`. This only applies to
6500 /// descendents of this `Node` which are using sysmem(1), not to this
6501 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
6502 /// token, which will fail allocation unless an ancestor of this `Node`
6503 /// specified `for_child_nodes_also` true.
6504 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
6505 self.client.send::<NodeSetWeakOkRequest>(
6506 &mut payload,
6507 0x38a44fc4d7724be9,
6508 fidl::encoding::DynamicFlags::FLEXIBLE,
6509 )
6510 }
6511
6512 /// The server_end will be closed after this `Node` and any child nodes have
6513 /// have released their buffer counts, making those counts available for
6514 /// reservation by a different `Node` via
6515 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
6516 ///
6517 /// The `Node` buffer counts may not be released until the entire tree of
6518 /// `Node`(s) is closed or failed, because
6519 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
6520 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
6521 /// `Node` buffer counts remain reserved until the orphaned node is later
6522 /// cleaned up.
6523 ///
6524 /// If the `Node` exceeds a fairly large number of attached eventpair server
6525 /// ends, a log message will indicate this and the `Node` (and the
6526 /// appropriate) sub-tree will fail.
6527 ///
6528 /// The `server_end` will remain open when
6529 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
6530 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
6531 /// [`fuchsia.sysmem2/BufferCollection`].
6532 ///
6533 /// This message can also be used with a
6534 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
6535 pub fn r#attach_node_tracking(
6536 &self,
6537 mut payload: NodeAttachNodeTrackingRequest,
6538 ) -> Result<(), fidl::Error> {
6539 self.client.send::<NodeAttachNodeTrackingRequest>(
6540 &mut payload,
6541 0x3f22f2a293d3cdac,
6542 fidl::encoding::DynamicFlags::FLEXIBLE,
6543 )
6544 }
6545
6546 /// Create additional [`fuchsia.sysmem2/BufferCollectionToken`](s) from this
6547 /// one, referring to the same buffer collection.
6548 ///
6549 /// The created tokens are children of this token in the
6550 /// [`fuchsia.sysmem2/Node`] heirarchy.
6551 ///
6552 /// This method can be used to add more participants, by transferring the
6553 /// newly created tokens to additional participants.
6554 ///
6555 /// A new token will be returned for each entry in the
6556 /// `rights_attenuation_masks` array.
6557 ///
6558 /// If the called token may not actually be a valid token due to a
6559 /// potentially hostile/untrusted provider of the token, consider using
6560 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
6561 /// instead of potentially getting stuck indefinitely if
6562 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] never responds
6563 /// due to the calling token not being a real token.
6564 ///
6565 /// In contrast to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], no
6566 /// separate [`fuchsia.sysmem2/Node.Sync`] is needed after calling this
6567 /// method, because the sync step is included in this call, at the cost of a
6568 /// round trip during this call.
6569 ///
6570 /// All tokens must be turned in to sysmem via
6571 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
6572 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
6573 /// successfully allocate buffers (or to logically allocate buffers in the
6574 /// case of subtrees involving
6575 /// [`fuchsia.sysmem2/BufferCollectionToken.AttachToken`]).
6576 ///
6577 /// All table fields are currently required.
6578 ///
6579 /// + request `rights_attenuation_mask` In each entry of
6580 /// `rights_attenuation_masks`, rights bits that are zero will be absent
6581 /// in the buffer VMO rights obtainable via the corresponding returned
6582 /// token. This allows an initiator or intermediary participant to
6583 /// attenuate the rights available to a participant. This does not allow a
6584 /// participant to gain rights that the participant doesn't already have.
6585 /// The value `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no
6586 /// attenuation should be applied.
6587 /// - response `tokens` The client ends of each newly created token.
6588 pub fn r#duplicate_sync(
6589 &self,
6590 mut payload: &BufferCollectionTokenDuplicateSyncRequest,
6591 ___deadline: zx::MonotonicInstant,
6592 ) -> Result<BufferCollectionTokenDuplicateSyncResponse, fidl::Error> {
6593 let _response = self.client.send_query::<
6594 BufferCollectionTokenDuplicateSyncRequest,
6595 fidl::encoding::FlexibleType<BufferCollectionTokenDuplicateSyncResponse>,
6596 BufferCollectionTokenMarker,
6597 >(
6598 payload,
6599 0x1c1af9919d1ca45c,
6600 fidl::encoding::DynamicFlags::FLEXIBLE,
6601 ___deadline,
6602 )?
6603 .into_result::<BufferCollectionTokenMarker>("duplicate_sync")?;
6604 Ok(_response)
6605 }
6606
6607 /// Create an additional [`fuchsia.sysmem2/BufferCollectionToken`] from this
6608 /// one, referring to the same buffer collection.
6609 ///
6610 /// The created token is a child of this token in the
6611 /// [`fuchsia.sysmem2/Node`] heirarchy.
6612 ///
6613 /// This method can be used to add a participant, by transferring the newly
6614 /// created token to another participant.
6615 ///
6616 /// This one-way message can be used instead of the two-way
6617 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] FIDL call in
6618 /// performance sensitive cases where it would be undesireable to wait for
6619 /// sysmem to respond to
6620 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] or when the
6621 /// client code isn't structured to make it easy to duplicate all the needed
6622 /// tokens at once.
6623 ///
6624 /// After sending one or more `Duplicate` messages, and before sending the
6625 /// newly created child tokens to other participants (or to other
6626 /// [`fuchsia.sysmem2/Allocator`] channels), the client must send a
6627 /// [`fuchsia.sysmem2/Node.Sync`] and wait for the `Sync` response. The
6628 /// `Sync` call can be made on the token, or on the `BufferCollection`
6629 /// obtained by passing this token to `BindSharedCollection`. Either will
6630 /// ensure that the server knows about the tokens created via `Duplicate`
6631 /// before the other participant sends the token to the server via separate
6632 /// `Allocator` channel.
6633 ///
6634 /// All tokens must be turned in via
6635 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
6636 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
6637 /// successfully allocate buffers.
6638 ///
6639 /// All table fields are currently required.
6640 ///
6641 /// + request `rights_attenuation_mask` The rights bits that are zero in
6642 /// this mask will be absent in the buffer VMO rights obtainable via the
6643 /// client end of `token_request`. This allows an initiator or
6644 /// intermediary participant to attenuate the rights available to a
6645 /// delegate participant. This does not allow a participant to gain rights
6646 /// that the participant doesn't already have. The value
6647 /// `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no attenuation
6648 /// should be applied.
6649 /// + These values for rights_attenuation_mask result in no attenuation:
6650 /// + `ZX_RIGHT_SAME_RIGHTS` (preferred)
6651 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is
6652 /// computed)
6653 /// + 0 (deprecated - do not use 0 - an ERROR will go to the log)
6654 /// + request `token_request` is the server end of a `BufferCollectionToken`
6655 /// channel. The client end of this channel acts as another participant in
6656 /// the shared buffer collection.
6657 pub fn r#duplicate(
6658 &self,
6659 mut payload: BufferCollectionTokenDuplicateRequest,
6660 ) -> Result<(), fidl::Error> {
6661 self.client.send::<BufferCollectionTokenDuplicateRequest>(
6662 &mut payload,
6663 0x73e78f92ee7fb887,
6664 fidl::encoding::DynamicFlags::FLEXIBLE,
6665 )
6666 }
6667
6668 /// Set this [`fuchsia.sysmem2/BufferCollectionToken`] to dispensable.
6669 ///
6670 /// When the `BufferCollectionToken` is converted to a
6671 /// [`fuchsia.sysmem2/BufferCollection`], the dispensable status applies to
6672 /// the `BufferCollection` also.
6673 ///
6674 /// Normally, if a client closes a [`fuchsia.sysmem2/BufferCollection`]
6675 /// client end without having sent
6676 /// [`fuchsia.sysmem2/BufferCollection.Release`] first, the
6677 /// `BufferCollection` [`fuchisa.sysmem2/Node`] will fail, which also
6678 /// propagates failure to the parent [`fuchsia.sysmem2/Node`] and so on up
6679 /// to the root `Node`, which fails the whole buffer collection. In
6680 /// contrast, a dispensable `Node` can fail after buffers are allocated
6681 /// without causing failure of its parent in the [`fuchsia.sysmem2/Node`]
6682 /// heirarchy.
6683 ///
6684 /// The dispensable `Node` participates in constraints aggregation along
6685 /// with its parent before buffer allocation. If the dispensable `Node`
6686 /// fails before buffers are allocated, the failure propagates to the
6687 /// dispensable `Node`'s parent.
6688 ///
6689 /// After buffers are allocated, failure of the dispensable `Node` (or any
6690 /// child of the dispensable `Node`) does not propagate to the dispensable
6691 /// `Node`'s parent. Failure does propagate from a normal child of a
6692 /// dispensable `Node` to the dispensable `Node`. Failure of a child is
6693 /// blocked from reaching its parent if the child is attached using
6694 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or if the child is
6695 /// dispensable and the failure occurred after allocation.
6696 ///
6697 /// A dispensable `Node` can be used in cases where a participant needs to
6698 /// provide constraints, but after buffers are allocated, the participant
6699 /// can fail without causing buffer collection failure from the parent
6700 /// `Node`'s point of view.
6701 ///
6702 /// In contrast, `BufferCollection.AttachToken` can be used to create a
6703 /// `BufferCollectionToken` which does not participate in constraints
6704 /// aggregation with its parent `Node`, and whose failure at any time does
6705 /// not propagate to its parent `Node`, and whose potential delay providing
6706 /// constraints does not prevent the parent `Node` from completing its
6707 /// buffer allocation.
6708 ///
6709 /// An initiator (creator of the root `Node` using
6710 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`]) may in some
6711 /// scenarios choose to initially use a dispensable `Node` for a first
6712 /// instance of a participant, and then later if the first instance of that
6713 /// participant fails, a new second instance of that participant my be given
6714 /// a `BufferCollectionToken` created with `AttachToken`.
6715 ///
6716 /// Normally a client will `SetDispensable` on a `BufferCollectionToken`
6717 /// shortly before sending the dispensable `BufferCollectionToken` to a
6718 /// delegate participant. Because `SetDispensable` prevents propagation of
6719 /// child `Node` failure to parent `Node`(s), if the client was relying on
6720 /// noticing child failure via failure of the parent `Node` retained by the
6721 /// client, the client may instead need to notice failure via other means.
6722 /// If other means aren't available/convenient, the client can instead
6723 /// retain the dispensable `Node` and create a child `Node` under that to
6724 /// send to the delegate participant, retaining this `Node` in order to
6725 /// notice failure of the subtree rooted at this `Node` via this `Node`'s
6726 /// ZX_CHANNEL_PEER_CLOSED signal, and take whatever action is appropriate
6727 /// (e.g. starting a new instance of the delegate participant and handing it
6728 /// a `BufferCollectionToken` created using
6729 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or propagate failure
6730 /// and clean up in a client-specific way).
6731 ///
6732 /// While it is possible (and potentially useful) to `SetDispensable` on a
6733 /// direct child of a `BufferCollectionTokenGroup` `Node`, it isn't possible
6734 /// to later replace a failed dispensable `Node` that was a direct child of
6735 /// a `BufferCollectionTokenGroup` with a new token using `AttachToken`
6736 /// (since there's no `AttachToken` on a group). Instead, to enable
6737 /// `AttachToken` replacement in this case, create an additional
6738 /// non-dispensable token that's a direct child of the group and make the
6739 /// existing dispensable token a child of the additional token. This way,
6740 /// the additional token that is a direct child of the group has
6741 /// `BufferCollection.AttachToken` which can be used to replace the failed
6742 /// dispensable token.
6743 ///
6744 /// `SetDispensable` on an already-dispensable token is idempotent.
6745 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
6746 self.client.send::<fidl::encoding::EmptyPayload>(
6747 (),
6748 0x228acf979254df8b,
6749 fidl::encoding::DynamicFlags::FLEXIBLE,
6750 )
6751 }
6752
6753 /// Create a logical OR among a set of tokens, called a
6754 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
6755 ///
6756 /// Most sysmem clients and many participants don't need to care about this
6757 /// message or about `BufferCollectionTokenGroup`(s). However, in some cases
6758 /// a participant wants to attempt to include one set of delegate
6759 /// participants, but if constraints don't combine successfully that way,
6760 /// fall back to a different (possibly overlapping) set of delegate
6761 /// participants, and/or fall back to a less demanding strategy (in terms of
6762 /// how strict the [`fuchisa.sysmem2/BufferCollectionConstraints`] are,
6763 /// across all involved delegate participants). In such cases, a
6764 /// `BufferCollectionTokenGroup` is useful.
6765 ///
6766 /// A `BufferCollectionTokenGroup` is used to create a 1 of N OR among N
6767 /// child [`fuchsia.sysmem2/BufferCollectionToken`](s). The child tokens
6768 /// which are not selected during aggregation will fail (close), which a
6769 /// potential participant should notice when their `BufferCollection`
6770 /// channel client endpoint sees PEER_CLOSED, allowing the participant to
6771 /// clean up the speculative usage that didn't end up happening (this is
6772 /// simimlar to a normal `BufferCollection` server end closing on failure to
6773 /// allocate a logical buffer collection or later async failure of a buffer
6774 /// collection).
6775 ///
6776 /// See comments on protocol `BufferCollectionTokenGroup`.
6777 ///
6778 /// Any `rights_attenuation_mask` or `AttachToken`/`SetDispensable` to be
6779 /// applied to the whole group can be achieved with a
6780 /// `BufferCollectionToken` for this purpose as a direct parent of the
6781 /// `BufferCollectionTokenGroup`.
6782 ///
6783 /// All table fields are currently required.
6784 ///
6785 /// + request `group_request` The server end of a
6786 /// `BufferCollectionTokenGroup` channel to be served by sysmem.
6787 pub fn r#create_buffer_collection_token_group(
6788 &self,
6789 mut payload: BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
6790 ) -> Result<(), fidl::Error> {
6791 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
6792 &mut payload,
6793 0x30f8d48e77bd36f2,
6794 fidl::encoding::DynamicFlags::FLEXIBLE,
6795 )
6796 }
6797}
6798
6799#[cfg(target_os = "fuchsia")]
6800impl From<BufferCollectionTokenSynchronousProxy> for zx::NullableHandle {
6801 fn from(value: BufferCollectionTokenSynchronousProxy) -> Self {
6802 value.into_channel().into()
6803 }
6804}
6805
6806#[cfg(target_os = "fuchsia")]
6807impl From<fidl::Channel> for BufferCollectionTokenSynchronousProxy {
6808 fn from(value: fidl::Channel) -> Self {
6809 Self::new(value)
6810 }
6811}
6812
6813#[cfg(target_os = "fuchsia")]
6814impl fidl::endpoints::FromClient for BufferCollectionTokenSynchronousProxy {
6815 type Protocol = BufferCollectionTokenMarker;
6816
6817 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>) -> Self {
6818 Self::new(value.into_channel())
6819 }
6820}
6821
6822#[derive(Debug, Clone)]
6823pub struct BufferCollectionTokenProxy {
6824 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
6825}
6826
6827impl fidl::endpoints::Proxy for BufferCollectionTokenProxy {
6828 type Protocol = BufferCollectionTokenMarker;
6829
6830 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
6831 Self::new(inner)
6832 }
6833
6834 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
6835 self.client.into_channel().map_err(|client| Self { client })
6836 }
6837
6838 fn as_channel(&self) -> &::fidl::AsyncChannel {
6839 self.client.as_channel()
6840 }
6841}
6842
6843impl BufferCollectionTokenProxy {
6844 /// Create a new Proxy for fuchsia.sysmem2/BufferCollectionToken.
6845 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
6846 let protocol_name =
6847 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
6848 Self { client: fidl::client::Client::new(channel, protocol_name) }
6849 }
6850
6851 /// Get a Stream of events from the remote end of the protocol.
6852 ///
6853 /// # Panics
6854 ///
6855 /// Panics if the event stream was already taken.
6856 pub fn take_event_stream(&self) -> BufferCollectionTokenEventStream {
6857 BufferCollectionTokenEventStream { event_receiver: self.client.take_event_receiver() }
6858 }
6859
6860 /// Ensure that previous messages have been received server side. This is
6861 /// particularly useful after previous messages that created new tokens,
6862 /// because a token must be known to the sysmem server before sending the
6863 /// token to another participant.
6864 ///
6865 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
6866 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
6867 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
6868 /// to mitigate the possibility of a hostile/fake
6869 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
6870 /// Another way is to pass the token to
6871 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
6872 /// the token as part of exchanging it for a
6873 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
6874 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
6875 /// of stalling.
6876 ///
6877 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
6878 /// and then starting and completing a `Sync`, it's then safe to send the
6879 /// `BufferCollectionToken` client ends to other participants knowing the
6880 /// server will recognize the tokens when they're sent by the other
6881 /// participants to sysmem in a
6882 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
6883 /// efficient way to create tokens while avoiding unnecessary round trips.
6884 ///
6885 /// Other options include waiting for each
6886 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
6887 /// individually (using separate call to `Sync` after each), or calling
6888 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
6889 /// converted to a `BufferCollection` via
6890 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
6891 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
6892 /// the sync step and can create multiple tokens at once.
6893 pub fn r#sync(
6894 &self,
6895 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
6896 BufferCollectionTokenProxyInterface::r#sync(self)
6897 }
6898
6899 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
6900 ///
6901 /// Normally a participant will convert a `BufferCollectionToken` into a
6902 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
6903 /// `Release` via the token (and then close the channel immediately or
6904 /// shortly later in response to server closing the server end), which
6905 /// avoids causing buffer collection failure. Without a prior `Release`,
6906 /// closing the `BufferCollectionToken` client end will cause buffer
6907 /// collection failure.
6908 ///
6909 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
6910 ///
6911 /// By default the server handles unexpected closure of a
6912 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
6913 /// first) by failing the buffer collection. Partly this is to expedite
6914 /// closing VMO handles to reclaim memory when any participant fails. If a
6915 /// participant would like to cleanly close a `BufferCollection` without
6916 /// causing buffer collection failure, the participant can send `Release`
6917 /// before closing the `BufferCollection` client end. The `Release` can
6918 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
6919 /// buffer collection won't require constraints from this node in order to
6920 /// allocate. If after `SetConstraints`, the constraints are retained and
6921 /// aggregated, despite the lack of `BufferCollection` connection at the
6922 /// time of constraints aggregation.
6923 ///
6924 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
6925 ///
6926 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
6927 /// end (without `Release` first) will trigger failure of the buffer
6928 /// collection. To close a `BufferCollectionTokenGroup` channel without
6929 /// failing the buffer collection, ensure that AllChildrenPresent() has been
6930 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
6931 /// client end.
6932 ///
6933 /// If `Release` occurs before
6934 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
6935 /// buffer collection will fail (triggered by reception of `Release` without
6936 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
6937 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
6938 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
6939 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
6940 /// close requires `AllChildrenPresent` (if not already sent), then
6941 /// `Release`, then close client end.
6942 ///
6943 /// If `Release` occurs after `AllChildrenPresent`, the children and all
6944 /// their constraints remain intact (just as they would if the
6945 /// `BufferCollectionTokenGroup` channel had remained open), and the client
6946 /// end close doesn't trigger buffer collection failure.
6947 ///
6948 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
6949 ///
6950 /// For brevity, the per-channel-protocol paragraphs above ignore the
6951 /// separate failure domain created by
6952 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
6953 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
6954 /// unexpectedly closes (without `Release` first) and that client end is
6955 /// under a failure domain, instead of failing the whole buffer collection,
6956 /// the failure domain is failed, but the buffer collection itself is
6957 /// isolated from failure of the failure domain. Such failure domains can be
6958 /// nested, in which case only the inner-most failure domain in which the
6959 /// `Node` resides fails.
6960 pub fn r#release(&self) -> Result<(), fidl::Error> {
6961 BufferCollectionTokenProxyInterface::r#release(self)
6962 }
6963
6964 /// Set a name for VMOs in this buffer collection.
6965 ///
6966 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
6967 /// will be truncated to fit. The name of the vmo will be suffixed with the
6968 /// buffer index within the collection (if the suffix fits within
6969 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
6970 /// listed in the inspect data.
6971 ///
6972 /// The name only affects VMOs allocated after the name is set; this call
6973 /// does not rename existing VMOs. If multiple clients set different names
6974 /// then the larger priority value will win. Setting a new name with the
6975 /// same priority as a prior name doesn't change the name.
6976 ///
6977 /// All table fields are currently required.
6978 ///
6979 /// + request `priority` The name is only set if this is the first `SetName`
6980 /// or if `priority` is greater than any previous `priority` value in
6981 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
6982 /// + request `name` The name for VMOs created under this buffer collection.
6983 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
6984 BufferCollectionTokenProxyInterface::r#set_name(self, payload)
6985 }
6986
6987 /// Set information about the current client that can be used by sysmem to
6988 /// help diagnose leaking memory and allocation stalls waiting for a
6989 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
6990 ///
6991 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
6992 /// `Node`(s) derived from this `Node`, unless overriden by
6993 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
6994 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
6995 ///
6996 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
6997 /// `Allocator` is the most efficient way to ensure that all
6998 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
6999 /// set, and is also more efficient than separately sending the same debug
7000 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
7001 /// created [`fuchsia.sysmem2/Node`].
7002 ///
7003 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
7004 /// indicate which client is closing their channel first, leading to subtree
7005 /// failure (which can be normal if the purpose of the subtree is over, but
7006 /// if happening earlier than expected, the client-channel-specific name can
7007 /// help diagnose where the failure is first coming from, from sysmem's
7008 /// point of view).
7009 ///
7010 /// All table fields are currently required.
7011 ///
7012 /// + request `name` This can be an arbitrary string, but the current
7013 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
7014 /// + request `id` This can be an arbitrary id, but the current process ID
7015 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
7016 pub fn r#set_debug_client_info(
7017 &self,
7018 mut payload: &NodeSetDebugClientInfoRequest,
7019 ) -> Result<(), fidl::Error> {
7020 BufferCollectionTokenProxyInterface::r#set_debug_client_info(self, payload)
7021 }
7022
7023 /// Sysmem logs a warning if sysmem hasn't seen
7024 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
7025 /// within 5 seconds after creation of a new collection.
7026 ///
7027 /// Clients can call this method to change when the log is printed. If
7028 /// multiple client set the deadline, it's unspecified which deadline will
7029 /// take effect.
7030 ///
7031 /// In most cases the default works well.
7032 ///
7033 /// All table fields are currently required.
7034 ///
7035 /// + request `deadline` The time at which sysmem will start trying to log
7036 /// the warning, unless all constraints are with sysmem by then.
7037 pub fn r#set_debug_timeout_log_deadline(
7038 &self,
7039 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
7040 ) -> Result<(), fidl::Error> {
7041 BufferCollectionTokenProxyInterface::r#set_debug_timeout_log_deadline(self, payload)
7042 }
7043
7044 /// This enables verbose logging for the buffer collection.
7045 ///
7046 /// Verbose logging includes constraints set via
7047 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
7048 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
7049 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
7050 /// the tree of `Node`(s).
7051 ///
7052 /// Normally sysmem prints only a single line complaint when aggregation
7053 /// fails, with just the specific detailed reason that aggregation failed,
7054 /// with little surrounding context. While this is often enough to diagnose
7055 /// a problem if only a small change was made and everything was working
7056 /// before the small change, it's often not particularly helpful for getting
7057 /// a new buffer collection to work for the first time. Especially with
7058 /// more complex trees of nodes, involving things like
7059 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
7060 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
7061 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
7062 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
7063 /// looks like and why it's failing a logical allocation, or why a tree or
7064 /// subtree is failing sooner than expected.
7065 ///
7066 /// The intent of the extra logging is to be acceptable from a performance
7067 /// point of view, under the assumption that verbose logging is only enabled
7068 /// on a low number of buffer collections. If we're not tracking down a bug,
7069 /// we shouldn't send this message.
7070 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7071 BufferCollectionTokenProxyInterface::r#set_verbose_logging(self)
7072 }
7073
7074 /// This gets a handle that can be used as a parameter to
7075 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
7076 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
7077 /// client obtained this handle from this `Node`.
7078 ///
7079 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
7080 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
7081 /// despite the two calls typically being on different channels.
7082 ///
7083 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
7084 ///
7085 /// All table fields are currently required.
7086 ///
7087 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
7088 /// different `Node` channel, to prove that the client obtained the handle
7089 /// from this `Node`.
7090 pub fn r#get_node_ref(
7091 &self,
7092 ) -> fidl::client::QueryResponseFut<
7093 NodeGetNodeRefResponse,
7094 fidl::encoding::DefaultFuchsiaResourceDialect,
7095 > {
7096 BufferCollectionTokenProxyInterface::r#get_node_ref(self)
7097 }
7098
7099 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
7100 /// rooted at a different child token of a common parent
7101 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
7102 /// passed-in `node_ref`.
7103 ///
7104 /// This call is for assisting with admission control de-duplication, and
7105 /// with debugging.
7106 ///
7107 /// The `node_ref` must be obtained using
7108 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
7109 ///
7110 /// The `node_ref` can be a duplicated handle; it's not necessary to call
7111 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
7112 ///
7113 /// If a calling token may not actually be a valid token at all due to a
7114 /// potentially hostile/untrusted provider of the token, call
7115 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
7116 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
7117 /// never responds due to a calling token not being a real token (not really
7118 /// talking to sysmem). Another option is to call
7119 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
7120 /// which also validates the token along with converting it to a
7121 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
7122 ///
7123 /// All table fields are currently required.
7124 ///
7125 /// - response `is_alternate`
7126 /// - true: The first parent node in common between the calling node and
7127 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
7128 /// that the calling `Node` and the `node_ref` `Node` will not have both
7129 /// their constraints apply - rather sysmem will choose one or the other
7130 /// of the constraints - never both. This is because only one child of
7131 /// a `BufferCollectionTokenGroup` is selected during logical
7132 /// allocation, with only that one child's subtree contributing to
7133 /// constraints aggregation.
7134 /// - false: The first parent node in common between the calling `Node`
7135 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
7136 /// Currently, this means the first parent node in common is a
7137 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
7138 /// `Release`ed). This means that the calling `Node` and the `node_ref`
7139 /// `Node` may have both their constraints apply during constraints
7140 /// aggregation of the logical allocation, if both `Node`(s) are
7141 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
7142 /// this case, there is no `BufferCollectionTokenGroup` that will
7143 /// directly prevent the two `Node`(s) from both being selected and
7144 /// their constraints both aggregated, but even when false, one or both
7145 /// `Node`(s) may still be eliminated from consideration if one or both
7146 /// `Node`(s) has a direct or indirect parent
7147 /// `BufferCollectionTokenGroup` which selects a child subtree other
7148 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
7149 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
7150 /// associated with the same buffer collection as the calling `Node`.
7151 /// Another reason for this error is if the `node_ref` is an
7152 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
7153 /// a real `node_ref` obtained from `GetNodeRef`.
7154 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
7155 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
7156 /// the needed rights expected on a real `node_ref`.
7157 /// * No other failing status codes are returned by this call. However,
7158 /// sysmem may add additional codes in future, so the client should have
7159 /// sensible default handling for any failing status code.
7160 pub fn r#is_alternate_for(
7161 &self,
7162 mut payload: NodeIsAlternateForRequest,
7163 ) -> fidl::client::QueryResponseFut<
7164 NodeIsAlternateForResult,
7165 fidl::encoding::DefaultFuchsiaResourceDialect,
7166 > {
7167 BufferCollectionTokenProxyInterface::r#is_alternate_for(self, payload)
7168 }
7169
7170 /// Get the buffer collection ID. This ID is also available from
7171 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
7172 /// within the collection).
7173 ///
7174 /// This call is mainly useful in situations where we can't convey a
7175 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
7176 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
7177 /// handle, which can be joined back up with a `BufferCollection` client end
7178 /// that was created via a different path. Prefer to convey a
7179 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
7180 ///
7181 /// Trusting a `buffer_collection_id` value from a source other than sysmem
7182 /// is analogous to trusting a koid value from a source other than zircon.
7183 /// Both should be avoided unless really necessary, and both require
7184 /// caution. In some situations it may be reasonable to refer to a
7185 /// pre-established `BufferCollection` by `buffer_collection_id` via a
7186 /// protocol for efficiency reasons, but an incoming value purporting to be
7187 /// a `buffer_collection_id` is not sufficient alone to justify granting the
7188 /// sender of the `buffer_collection_id` any capability. The sender must
7189 /// first prove to a receiver that the sender has/had a VMO or has/had a
7190 /// `BufferCollectionToken` to the same collection by sending a handle that
7191 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
7192 /// `buffer_collection_id` value. The receiver should take care to avoid
7193 /// assuming that a sender had a `BufferCollectionToken` in cases where the
7194 /// sender has only proven that the sender had a VMO.
7195 ///
7196 /// - response `buffer_collection_id` This ID is unique per buffer
7197 /// collection per boot. Each buffer is uniquely identified by the
7198 /// `buffer_collection_id` and `buffer_index` together.
7199 pub fn r#get_buffer_collection_id(
7200 &self,
7201 ) -> fidl::client::QueryResponseFut<
7202 NodeGetBufferCollectionIdResponse,
7203 fidl::encoding::DefaultFuchsiaResourceDialect,
7204 > {
7205 BufferCollectionTokenProxyInterface::r#get_buffer_collection_id(self)
7206 }
7207
7208 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
7209 /// created after this message to weak, which means that a client's `Node`
7210 /// client end (or a child created after this message) is not alone
7211 /// sufficient to keep allocated VMOs alive.
7212 ///
7213 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
7214 /// `close_weak_asap`.
7215 ///
7216 /// This message is only permitted before the `Node` becomes ready for
7217 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
7218 /// * `BufferCollectionToken`: any time
7219 /// * `BufferCollection`: before `SetConstraints`
7220 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
7221 ///
7222 /// Currently, no conversion from strong `Node` to weak `Node` after ready
7223 /// for allocation is provided, but a client can simulate that by creating
7224 /// an additional `Node` before allocation and setting that additional
7225 /// `Node` to weak, and then potentially at some point later sending
7226 /// `Release` and closing the client end of the client's strong `Node`, but
7227 /// keeping the client's weak `Node`.
7228 ///
7229 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
7230 /// collection failure (all `Node` client end(s) will see
7231 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
7232 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
7233 /// this situation until all `Node`(s) are ready for allocation. For initial
7234 /// allocation to succeed, at least one strong `Node` is required to exist
7235 /// at allocation time, but after that client receives VMO handles, that
7236 /// client can `BufferCollection.Release` and close the client end without
7237 /// causing this type of failure.
7238 ///
7239 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
7240 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
7241 /// separately as appropriate.
7242 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
7243 BufferCollectionTokenProxyInterface::r#set_weak(self)
7244 }
7245
7246 /// This indicates to sysmem that the client is prepared to pay attention to
7247 /// `close_weak_asap`.
7248 ///
7249 /// If sent, this message must be before
7250 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
7251 ///
7252 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
7253 /// send this message before `WaitForAllBuffersAllocated`, or a parent
7254 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
7255 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
7256 /// trigger buffer collection failure.
7257 ///
7258 /// This message is necessary because weak sysmem VMOs have not always been
7259 /// a thing, so older clients are not aware of the need to pay attention to
7260 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
7261 /// sysmem weak VMO handles asap. By having this message and requiring
7262 /// participants to indicate their acceptance of this aspect of the overall
7263 /// protocol, we avoid situations where an older client is delivered a weak
7264 /// VMO without any way for sysmem to get that VMO to close quickly later
7265 /// (and on a per-buffer basis).
7266 ///
7267 /// A participant that doesn't handle `close_weak_asap` and also doesn't
7268 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
7269 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
7270 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
7271 /// same participant has a child/delegate which does retrieve VMOs, that
7272 /// child/delegate will need to send `SetWeakOk` before
7273 /// `WaitForAllBuffersAllocated`.
7274 ///
7275 /// + request `for_child_nodes_also` If present and true, this means direct
7276 /// child nodes of this node created after this message plus all
7277 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
7278 /// those nodes. Any child node of this node that was created before this
7279 /// message is not included. This setting is "sticky" in the sense that a
7280 /// subsequent `SetWeakOk` without this bool set to true does not reset
7281 /// the server-side bool. If this creates a problem for a participant, a
7282 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
7283 /// tokens instead, as appropriate. A participant should only set
7284 /// `for_child_nodes_also` true if the participant can really promise to
7285 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
7286 /// weak VMO handles held by participants holding the corresponding child
7287 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
7288 /// which are using sysmem(1) can be weak, despite the clients of those
7289 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
7290 /// direct way to find out about `close_weak_asap`. This only applies to
7291 /// descendents of this `Node` which are using sysmem(1), not to this
7292 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
7293 /// token, which will fail allocation unless an ancestor of this `Node`
7294 /// specified `for_child_nodes_also` true.
7295 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
7296 BufferCollectionTokenProxyInterface::r#set_weak_ok(self, payload)
7297 }
7298
7299 /// The server_end will be closed after this `Node` and any child nodes have
7300 /// have released their buffer counts, making those counts available for
7301 /// reservation by a different `Node` via
7302 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
7303 ///
7304 /// The `Node` buffer counts may not be released until the entire tree of
7305 /// `Node`(s) is closed or failed, because
7306 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
7307 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
7308 /// `Node` buffer counts remain reserved until the orphaned node is later
7309 /// cleaned up.
7310 ///
7311 /// If the `Node` exceeds a fairly large number of attached eventpair server
7312 /// ends, a log message will indicate this and the `Node` (and the
7313 /// appropriate) sub-tree will fail.
7314 ///
7315 /// The `server_end` will remain open when
7316 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
7317 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
7318 /// [`fuchsia.sysmem2/BufferCollection`].
7319 ///
7320 /// This message can also be used with a
7321 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
7322 pub fn r#attach_node_tracking(
7323 &self,
7324 mut payload: NodeAttachNodeTrackingRequest,
7325 ) -> Result<(), fidl::Error> {
7326 BufferCollectionTokenProxyInterface::r#attach_node_tracking(self, payload)
7327 }
7328
7329 /// Create additional [`fuchsia.sysmem2/BufferCollectionToken`](s) from this
7330 /// one, referring to the same buffer collection.
7331 ///
7332 /// The created tokens are children of this token in the
7333 /// [`fuchsia.sysmem2/Node`] heirarchy.
7334 ///
7335 /// This method can be used to add more participants, by transferring the
7336 /// newly created tokens to additional participants.
7337 ///
7338 /// A new token will be returned for each entry in the
7339 /// `rights_attenuation_masks` array.
7340 ///
7341 /// If the called token may not actually be a valid token due to a
7342 /// potentially hostile/untrusted provider of the token, consider using
7343 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
7344 /// instead of potentially getting stuck indefinitely if
7345 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] never responds
7346 /// due to the calling token not being a real token.
7347 ///
7348 /// In contrast to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], no
7349 /// separate [`fuchsia.sysmem2/Node.Sync`] is needed after calling this
7350 /// method, because the sync step is included in this call, at the cost of a
7351 /// round trip during this call.
7352 ///
7353 /// All tokens must be turned in to sysmem via
7354 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
7355 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
7356 /// successfully allocate buffers (or to logically allocate buffers in the
7357 /// case of subtrees involving
7358 /// [`fuchsia.sysmem2/BufferCollectionToken.AttachToken`]).
7359 ///
7360 /// All table fields are currently required.
7361 ///
7362 /// + request `rights_attenuation_mask` In each entry of
7363 /// `rights_attenuation_masks`, rights bits that are zero will be absent
7364 /// in the buffer VMO rights obtainable via the corresponding returned
7365 /// token. This allows an initiator or intermediary participant to
7366 /// attenuate the rights available to a participant. This does not allow a
7367 /// participant to gain rights that the participant doesn't already have.
7368 /// The value `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no
7369 /// attenuation should be applied.
7370 /// - response `tokens` The client ends of each newly created token.
7371 pub fn r#duplicate_sync(
7372 &self,
7373 mut payload: &BufferCollectionTokenDuplicateSyncRequest,
7374 ) -> fidl::client::QueryResponseFut<
7375 BufferCollectionTokenDuplicateSyncResponse,
7376 fidl::encoding::DefaultFuchsiaResourceDialect,
7377 > {
7378 BufferCollectionTokenProxyInterface::r#duplicate_sync(self, payload)
7379 }
7380
7381 /// Create an additional [`fuchsia.sysmem2/BufferCollectionToken`] from this
7382 /// one, referring to the same buffer collection.
7383 ///
7384 /// The created token is a child of this token in the
7385 /// [`fuchsia.sysmem2/Node`] heirarchy.
7386 ///
7387 /// This method can be used to add a participant, by transferring the newly
7388 /// created token to another participant.
7389 ///
7390 /// This one-way message can be used instead of the two-way
7391 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] FIDL call in
7392 /// performance sensitive cases where it would be undesireable to wait for
7393 /// sysmem to respond to
7394 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] or when the
7395 /// client code isn't structured to make it easy to duplicate all the needed
7396 /// tokens at once.
7397 ///
7398 /// After sending one or more `Duplicate` messages, and before sending the
7399 /// newly created child tokens to other participants (or to other
7400 /// [`fuchsia.sysmem2/Allocator`] channels), the client must send a
7401 /// [`fuchsia.sysmem2/Node.Sync`] and wait for the `Sync` response. The
7402 /// `Sync` call can be made on the token, or on the `BufferCollection`
7403 /// obtained by passing this token to `BindSharedCollection`. Either will
7404 /// ensure that the server knows about the tokens created via `Duplicate`
7405 /// before the other participant sends the token to the server via separate
7406 /// `Allocator` channel.
7407 ///
7408 /// All tokens must be turned in via
7409 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
7410 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
7411 /// successfully allocate buffers.
7412 ///
7413 /// All table fields are currently required.
7414 ///
7415 /// + request `rights_attenuation_mask` The rights bits that are zero in
7416 /// this mask will be absent in the buffer VMO rights obtainable via the
7417 /// client end of `token_request`. This allows an initiator or
7418 /// intermediary participant to attenuate the rights available to a
7419 /// delegate participant. This does not allow a participant to gain rights
7420 /// that the participant doesn't already have. The value
7421 /// `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no attenuation
7422 /// should be applied.
7423 /// + These values for rights_attenuation_mask result in no attenuation:
7424 /// + `ZX_RIGHT_SAME_RIGHTS` (preferred)
7425 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is
7426 /// computed)
7427 /// + 0 (deprecated - do not use 0 - an ERROR will go to the log)
7428 /// + request `token_request` is the server end of a `BufferCollectionToken`
7429 /// channel. The client end of this channel acts as another participant in
7430 /// the shared buffer collection.
7431 pub fn r#duplicate(
7432 &self,
7433 mut payload: BufferCollectionTokenDuplicateRequest,
7434 ) -> Result<(), fidl::Error> {
7435 BufferCollectionTokenProxyInterface::r#duplicate(self, payload)
7436 }
7437
7438 /// Set this [`fuchsia.sysmem2/BufferCollectionToken`] to dispensable.
7439 ///
7440 /// When the `BufferCollectionToken` is converted to a
7441 /// [`fuchsia.sysmem2/BufferCollection`], the dispensable status applies to
7442 /// the `BufferCollection` also.
7443 ///
7444 /// Normally, if a client closes a [`fuchsia.sysmem2/BufferCollection`]
7445 /// client end without having sent
7446 /// [`fuchsia.sysmem2/BufferCollection.Release`] first, the
7447 /// `BufferCollection` [`fuchisa.sysmem2/Node`] will fail, which also
7448 /// propagates failure to the parent [`fuchsia.sysmem2/Node`] and so on up
7449 /// to the root `Node`, which fails the whole buffer collection. In
7450 /// contrast, a dispensable `Node` can fail after buffers are allocated
7451 /// without causing failure of its parent in the [`fuchsia.sysmem2/Node`]
7452 /// heirarchy.
7453 ///
7454 /// The dispensable `Node` participates in constraints aggregation along
7455 /// with its parent before buffer allocation. If the dispensable `Node`
7456 /// fails before buffers are allocated, the failure propagates to the
7457 /// dispensable `Node`'s parent.
7458 ///
7459 /// After buffers are allocated, failure of the dispensable `Node` (or any
7460 /// child of the dispensable `Node`) does not propagate to the dispensable
7461 /// `Node`'s parent. Failure does propagate from a normal child of a
7462 /// dispensable `Node` to the dispensable `Node`. Failure of a child is
7463 /// blocked from reaching its parent if the child is attached using
7464 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or if the child is
7465 /// dispensable and the failure occurred after allocation.
7466 ///
7467 /// A dispensable `Node` can be used in cases where a participant needs to
7468 /// provide constraints, but after buffers are allocated, the participant
7469 /// can fail without causing buffer collection failure from the parent
7470 /// `Node`'s point of view.
7471 ///
7472 /// In contrast, `BufferCollection.AttachToken` can be used to create a
7473 /// `BufferCollectionToken` which does not participate in constraints
7474 /// aggregation with its parent `Node`, and whose failure at any time does
7475 /// not propagate to its parent `Node`, and whose potential delay providing
7476 /// constraints does not prevent the parent `Node` from completing its
7477 /// buffer allocation.
7478 ///
7479 /// An initiator (creator of the root `Node` using
7480 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`]) may in some
7481 /// scenarios choose to initially use a dispensable `Node` for a first
7482 /// instance of a participant, and then later if the first instance of that
7483 /// participant fails, a new second instance of that participant my be given
7484 /// a `BufferCollectionToken` created with `AttachToken`.
7485 ///
7486 /// Normally a client will `SetDispensable` on a `BufferCollectionToken`
7487 /// shortly before sending the dispensable `BufferCollectionToken` to a
7488 /// delegate participant. Because `SetDispensable` prevents propagation of
7489 /// child `Node` failure to parent `Node`(s), if the client was relying on
7490 /// noticing child failure via failure of the parent `Node` retained by the
7491 /// client, the client may instead need to notice failure via other means.
7492 /// If other means aren't available/convenient, the client can instead
7493 /// retain the dispensable `Node` and create a child `Node` under that to
7494 /// send to the delegate participant, retaining this `Node` in order to
7495 /// notice failure of the subtree rooted at this `Node` via this `Node`'s
7496 /// ZX_CHANNEL_PEER_CLOSED signal, and take whatever action is appropriate
7497 /// (e.g. starting a new instance of the delegate participant and handing it
7498 /// a `BufferCollectionToken` created using
7499 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or propagate failure
7500 /// and clean up in a client-specific way).
7501 ///
7502 /// While it is possible (and potentially useful) to `SetDispensable` on a
7503 /// direct child of a `BufferCollectionTokenGroup` `Node`, it isn't possible
7504 /// to later replace a failed dispensable `Node` that was a direct child of
7505 /// a `BufferCollectionTokenGroup` with a new token using `AttachToken`
7506 /// (since there's no `AttachToken` on a group). Instead, to enable
7507 /// `AttachToken` replacement in this case, create an additional
7508 /// non-dispensable token that's a direct child of the group and make the
7509 /// existing dispensable token a child of the additional token. This way,
7510 /// the additional token that is a direct child of the group has
7511 /// `BufferCollection.AttachToken` which can be used to replace the failed
7512 /// dispensable token.
7513 ///
7514 /// `SetDispensable` on an already-dispensable token is idempotent.
7515 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
7516 BufferCollectionTokenProxyInterface::r#set_dispensable(self)
7517 }
7518
7519 /// Create a logical OR among a set of tokens, called a
7520 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
7521 ///
7522 /// Most sysmem clients and many participants don't need to care about this
7523 /// message or about `BufferCollectionTokenGroup`(s). However, in some cases
7524 /// a participant wants to attempt to include one set of delegate
7525 /// participants, but if constraints don't combine successfully that way,
7526 /// fall back to a different (possibly overlapping) set of delegate
7527 /// participants, and/or fall back to a less demanding strategy (in terms of
7528 /// how strict the [`fuchisa.sysmem2/BufferCollectionConstraints`] are,
7529 /// across all involved delegate participants). In such cases, a
7530 /// `BufferCollectionTokenGroup` is useful.
7531 ///
7532 /// A `BufferCollectionTokenGroup` is used to create a 1 of N OR among N
7533 /// child [`fuchsia.sysmem2/BufferCollectionToken`](s). The child tokens
7534 /// which are not selected during aggregation will fail (close), which a
7535 /// potential participant should notice when their `BufferCollection`
7536 /// channel client endpoint sees PEER_CLOSED, allowing the participant to
7537 /// clean up the speculative usage that didn't end up happening (this is
7538 /// simimlar to a normal `BufferCollection` server end closing on failure to
7539 /// allocate a logical buffer collection or later async failure of a buffer
7540 /// collection).
7541 ///
7542 /// See comments on protocol `BufferCollectionTokenGroup`.
7543 ///
7544 /// Any `rights_attenuation_mask` or `AttachToken`/`SetDispensable` to be
7545 /// applied to the whole group can be achieved with a
7546 /// `BufferCollectionToken` for this purpose as a direct parent of the
7547 /// `BufferCollectionTokenGroup`.
7548 ///
7549 /// All table fields are currently required.
7550 ///
7551 /// + request `group_request` The server end of a
7552 /// `BufferCollectionTokenGroup` channel to be served by sysmem.
7553 pub fn r#create_buffer_collection_token_group(
7554 &self,
7555 mut payload: BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
7556 ) -> Result<(), fidl::Error> {
7557 BufferCollectionTokenProxyInterface::r#create_buffer_collection_token_group(self, payload)
7558 }
7559}
7560
7561impl BufferCollectionTokenProxyInterface for BufferCollectionTokenProxy {
7562 type SyncResponseFut =
7563 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
7564 fn r#sync(&self) -> Self::SyncResponseFut {
7565 fn _decode(
7566 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7567 ) -> Result<(), fidl::Error> {
7568 let _response = fidl::client::decode_transaction_body::<
7569 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
7570 fidl::encoding::DefaultFuchsiaResourceDialect,
7571 0x11ac2555cf575b54,
7572 >(_buf?)?
7573 .into_result::<BufferCollectionTokenMarker>("sync")?;
7574 Ok(_response)
7575 }
7576 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
7577 (),
7578 0x11ac2555cf575b54,
7579 fidl::encoding::DynamicFlags::FLEXIBLE,
7580 _decode,
7581 )
7582 }
7583
7584 fn r#release(&self) -> Result<(), fidl::Error> {
7585 self.client.send::<fidl::encoding::EmptyPayload>(
7586 (),
7587 0x6a5cae7d6d6e04c6,
7588 fidl::encoding::DynamicFlags::FLEXIBLE,
7589 )
7590 }
7591
7592 fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
7593 self.client.send::<NodeSetNameRequest>(
7594 payload,
7595 0xb41f1624f48c1e9,
7596 fidl::encoding::DynamicFlags::FLEXIBLE,
7597 )
7598 }
7599
7600 fn r#set_debug_client_info(
7601 &self,
7602 mut payload: &NodeSetDebugClientInfoRequest,
7603 ) -> Result<(), fidl::Error> {
7604 self.client.send::<NodeSetDebugClientInfoRequest>(
7605 payload,
7606 0x5cde8914608d99b1,
7607 fidl::encoding::DynamicFlags::FLEXIBLE,
7608 )
7609 }
7610
7611 fn r#set_debug_timeout_log_deadline(
7612 &self,
7613 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
7614 ) -> Result<(), fidl::Error> {
7615 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
7616 payload,
7617 0x716b0af13d5c0806,
7618 fidl::encoding::DynamicFlags::FLEXIBLE,
7619 )
7620 }
7621
7622 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7623 self.client.send::<fidl::encoding::EmptyPayload>(
7624 (),
7625 0x5209c77415b4dfad,
7626 fidl::encoding::DynamicFlags::FLEXIBLE,
7627 )
7628 }
7629
7630 type GetNodeRefResponseFut = fidl::client::QueryResponseFut<
7631 NodeGetNodeRefResponse,
7632 fidl::encoding::DefaultFuchsiaResourceDialect,
7633 >;
7634 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
7635 fn _decode(
7636 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7637 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
7638 let _response = fidl::client::decode_transaction_body::<
7639 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
7640 fidl::encoding::DefaultFuchsiaResourceDialect,
7641 0x5b3d0e51614df053,
7642 >(_buf?)?
7643 .into_result::<BufferCollectionTokenMarker>("get_node_ref")?;
7644 Ok(_response)
7645 }
7646 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
7647 (),
7648 0x5b3d0e51614df053,
7649 fidl::encoding::DynamicFlags::FLEXIBLE,
7650 _decode,
7651 )
7652 }
7653
7654 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
7655 NodeIsAlternateForResult,
7656 fidl::encoding::DefaultFuchsiaResourceDialect,
7657 >;
7658 fn r#is_alternate_for(
7659 &self,
7660 mut payload: NodeIsAlternateForRequest,
7661 ) -> Self::IsAlternateForResponseFut {
7662 fn _decode(
7663 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7664 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
7665 let _response = fidl::client::decode_transaction_body::<
7666 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
7667 fidl::encoding::DefaultFuchsiaResourceDialect,
7668 0x3a58e00157e0825,
7669 >(_buf?)?
7670 .into_result::<BufferCollectionTokenMarker>("is_alternate_for")?;
7671 Ok(_response.map(|x| x))
7672 }
7673 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
7674 &mut payload,
7675 0x3a58e00157e0825,
7676 fidl::encoding::DynamicFlags::FLEXIBLE,
7677 _decode,
7678 )
7679 }
7680
7681 type GetBufferCollectionIdResponseFut = fidl::client::QueryResponseFut<
7682 NodeGetBufferCollectionIdResponse,
7683 fidl::encoding::DefaultFuchsiaResourceDialect,
7684 >;
7685 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut {
7686 fn _decode(
7687 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7688 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
7689 let _response = fidl::client::decode_transaction_body::<
7690 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
7691 fidl::encoding::DefaultFuchsiaResourceDialect,
7692 0x77d19a494b78ba8c,
7693 >(_buf?)?
7694 .into_result::<BufferCollectionTokenMarker>("get_buffer_collection_id")?;
7695 Ok(_response)
7696 }
7697 self.client.send_query_and_decode::<
7698 fidl::encoding::EmptyPayload,
7699 NodeGetBufferCollectionIdResponse,
7700 >(
7701 (),
7702 0x77d19a494b78ba8c,
7703 fidl::encoding::DynamicFlags::FLEXIBLE,
7704 _decode,
7705 )
7706 }
7707
7708 fn r#set_weak(&self) -> Result<(), fidl::Error> {
7709 self.client.send::<fidl::encoding::EmptyPayload>(
7710 (),
7711 0x22dd3ea514eeffe1,
7712 fidl::encoding::DynamicFlags::FLEXIBLE,
7713 )
7714 }
7715
7716 fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
7717 self.client.send::<NodeSetWeakOkRequest>(
7718 &mut payload,
7719 0x38a44fc4d7724be9,
7720 fidl::encoding::DynamicFlags::FLEXIBLE,
7721 )
7722 }
7723
7724 fn r#attach_node_tracking(
7725 &self,
7726 mut payload: NodeAttachNodeTrackingRequest,
7727 ) -> Result<(), fidl::Error> {
7728 self.client.send::<NodeAttachNodeTrackingRequest>(
7729 &mut payload,
7730 0x3f22f2a293d3cdac,
7731 fidl::encoding::DynamicFlags::FLEXIBLE,
7732 )
7733 }
7734
7735 type DuplicateSyncResponseFut = fidl::client::QueryResponseFut<
7736 BufferCollectionTokenDuplicateSyncResponse,
7737 fidl::encoding::DefaultFuchsiaResourceDialect,
7738 >;
7739 fn r#duplicate_sync(
7740 &self,
7741 mut payload: &BufferCollectionTokenDuplicateSyncRequest,
7742 ) -> Self::DuplicateSyncResponseFut {
7743 fn _decode(
7744 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7745 ) -> Result<BufferCollectionTokenDuplicateSyncResponse, fidl::Error> {
7746 let _response = fidl::client::decode_transaction_body::<
7747 fidl::encoding::FlexibleType<BufferCollectionTokenDuplicateSyncResponse>,
7748 fidl::encoding::DefaultFuchsiaResourceDialect,
7749 0x1c1af9919d1ca45c,
7750 >(_buf?)?
7751 .into_result::<BufferCollectionTokenMarker>("duplicate_sync")?;
7752 Ok(_response)
7753 }
7754 self.client.send_query_and_decode::<
7755 BufferCollectionTokenDuplicateSyncRequest,
7756 BufferCollectionTokenDuplicateSyncResponse,
7757 >(
7758 payload,
7759 0x1c1af9919d1ca45c,
7760 fidl::encoding::DynamicFlags::FLEXIBLE,
7761 _decode,
7762 )
7763 }
7764
7765 fn r#duplicate(
7766 &self,
7767 mut payload: BufferCollectionTokenDuplicateRequest,
7768 ) -> Result<(), fidl::Error> {
7769 self.client.send::<BufferCollectionTokenDuplicateRequest>(
7770 &mut payload,
7771 0x73e78f92ee7fb887,
7772 fidl::encoding::DynamicFlags::FLEXIBLE,
7773 )
7774 }
7775
7776 fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
7777 self.client.send::<fidl::encoding::EmptyPayload>(
7778 (),
7779 0x228acf979254df8b,
7780 fidl::encoding::DynamicFlags::FLEXIBLE,
7781 )
7782 }
7783
7784 fn r#create_buffer_collection_token_group(
7785 &self,
7786 mut payload: BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
7787 ) -> Result<(), fidl::Error> {
7788 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
7789 &mut payload,
7790 0x30f8d48e77bd36f2,
7791 fidl::encoding::DynamicFlags::FLEXIBLE,
7792 )
7793 }
7794}
7795
7796pub struct BufferCollectionTokenEventStream {
7797 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
7798}
7799
7800impl std::marker::Unpin for BufferCollectionTokenEventStream {}
7801
7802impl futures::stream::FusedStream for BufferCollectionTokenEventStream {
7803 fn is_terminated(&self) -> bool {
7804 self.event_receiver.is_terminated()
7805 }
7806}
7807
7808impl futures::Stream for BufferCollectionTokenEventStream {
7809 type Item = Result<BufferCollectionTokenEvent, fidl::Error>;
7810
7811 fn poll_next(
7812 mut self: std::pin::Pin<&mut Self>,
7813 cx: &mut std::task::Context<'_>,
7814 ) -> std::task::Poll<Option<Self::Item>> {
7815 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
7816 &mut self.event_receiver,
7817 cx
7818 )?) {
7819 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenEvent::decode(buf))),
7820 None => std::task::Poll::Ready(None),
7821 }
7822 }
7823}
7824
7825#[derive(Debug)]
7826pub enum BufferCollectionTokenEvent {
7827 #[non_exhaustive]
7828 _UnknownEvent {
7829 /// Ordinal of the event that was sent.
7830 ordinal: u64,
7831 },
7832}
7833
7834impl BufferCollectionTokenEvent {
7835 /// Decodes a message buffer as a [`BufferCollectionTokenEvent`].
7836 fn decode(
7837 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
7838 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
7839 let (bytes, _handles) = buf.split_mut();
7840 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7841 debug_assert_eq!(tx_header.tx_id, 0);
7842 match tx_header.ordinal {
7843 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
7844 Ok(BufferCollectionTokenEvent::_UnknownEvent { ordinal: tx_header.ordinal })
7845 }
7846 _ => Err(fidl::Error::UnknownOrdinal {
7847 ordinal: tx_header.ordinal,
7848 protocol_name:
7849 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
7850 }),
7851 }
7852 }
7853}
7854
7855/// A Stream of incoming requests for fuchsia.sysmem2/BufferCollectionToken.
7856pub struct BufferCollectionTokenRequestStream {
7857 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7858 is_terminated: bool,
7859}
7860
7861impl std::marker::Unpin for BufferCollectionTokenRequestStream {}
7862
7863impl futures::stream::FusedStream for BufferCollectionTokenRequestStream {
7864 fn is_terminated(&self) -> bool {
7865 self.is_terminated
7866 }
7867}
7868
7869impl fidl::endpoints::RequestStream for BufferCollectionTokenRequestStream {
7870 type Protocol = BufferCollectionTokenMarker;
7871 type ControlHandle = BufferCollectionTokenControlHandle;
7872
7873 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
7874 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
7875 }
7876
7877 fn control_handle(&self) -> Self::ControlHandle {
7878 BufferCollectionTokenControlHandle { inner: self.inner.clone() }
7879 }
7880
7881 fn into_inner(
7882 self,
7883 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
7884 {
7885 (self.inner, self.is_terminated)
7886 }
7887
7888 fn from_inner(
7889 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7890 is_terminated: bool,
7891 ) -> Self {
7892 Self { inner, is_terminated }
7893 }
7894}
7895
7896impl futures::Stream for BufferCollectionTokenRequestStream {
7897 type Item = Result<BufferCollectionTokenRequest, fidl::Error>;
7898
7899 fn poll_next(
7900 mut self: std::pin::Pin<&mut Self>,
7901 cx: &mut std::task::Context<'_>,
7902 ) -> std::task::Poll<Option<Self::Item>> {
7903 let this = &mut *self;
7904 if this.inner.check_shutdown(cx) {
7905 this.is_terminated = true;
7906 return std::task::Poll::Ready(None);
7907 }
7908 if this.is_terminated {
7909 panic!("polled BufferCollectionTokenRequestStream after completion");
7910 }
7911 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
7912 |bytes, handles| {
7913 match this.inner.channel().read_etc(cx, bytes, handles) {
7914 std::task::Poll::Ready(Ok(())) => {}
7915 std::task::Poll::Pending => return std::task::Poll::Pending,
7916 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
7917 this.is_terminated = true;
7918 return std::task::Poll::Ready(None);
7919 }
7920 std::task::Poll::Ready(Err(e)) => {
7921 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
7922 e.into(),
7923 ))));
7924 }
7925 }
7926
7927 // A message has been received from the channel
7928 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7929
7930 std::task::Poll::Ready(Some(match header.ordinal {
7931 0x11ac2555cf575b54 => {
7932 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7933 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7934 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7935 let control_handle = BufferCollectionTokenControlHandle {
7936 inner: this.inner.clone(),
7937 };
7938 Ok(BufferCollectionTokenRequest::Sync {
7939 responder: BufferCollectionTokenSyncResponder {
7940 control_handle: std::mem::ManuallyDrop::new(control_handle),
7941 tx_id: header.tx_id,
7942 },
7943 })
7944 }
7945 0x6a5cae7d6d6e04c6 => {
7946 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7947 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7948 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7949 let control_handle = BufferCollectionTokenControlHandle {
7950 inner: this.inner.clone(),
7951 };
7952 Ok(BufferCollectionTokenRequest::Release {
7953 control_handle,
7954 })
7955 }
7956 0xb41f1624f48c1e9 => {
7957 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7958 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7959 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
7960 let control_handle = BufferCollectionTokenControlHandle {
7961 inner: this.inner.clone(),
7962 };
7963 Ok(BufferCollectionTokenRequest::SetName {payload: req,
7964 control_handle,
7965 })
7966 }
7967 0x5cde8914608d99b1 => {
7968 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7969 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7970 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
7971 let control_handle = BufferCollectionTokenControlHandle {
7972 inner: this.inner.clone(),
7973 };
7974 Ok(BufferCollectionTokenRequest::SetDebugClientInfo {payload: req,
7975 control_handle,
7976 })
7977 }
7978 0x716b0af13d5c0806 => {
7979 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7980 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7981 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
7982 let control_handle = BufferCollectionTokenControlHandle {
7983 inner: this.inner.clone(),
7984 };
7985 Ok(BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {payload: req,
7986 control_handle,
7987 })
7988 }
7989 0x5209c77415b4dfad => {
7990 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7991 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7992 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7993 let control_handle = BufferCollectionTokenControlHandle {
7994 inner: this.inner.clone(),
7995 };
7996 Ok(BufferCollectionTokenRequest::SetVerboseLogging {
7997 control_handle,
7998 })
7999 }
8000 0x5b3d0e51614df053 => {
8001 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
8002 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
8003 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
8004 let control_handle = BufferCollectionTokenControlHandle {
8005 inner: this.inner.clone(),
8006 };
8007 Ok(BufferCollectionTokenRequest::GetNodeRef {
8008 responder: BufferCollectionTokenGetNodeRefResponder {
8009 control_handle: std::mem::ManuallyDrop::new(control_handle),
8010 tx_id: header.tx_id,
8011 },
8012 })
8013 }
8014 0x3a58e00157e0825 => {
8015 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
8016 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8017 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
8018 let control_handle = BufferCollectionTokenControlHandle {
8019 inner: this.inner.clone(),
8020 };
8021 Ok(BufferCollectionTokenRequest::IsAlternateFor {payload: req,
8022 responder: BufferCollectionTokenIsAlternateForResponder {
8023 control_handle: std::mem::ManuallyDrop::new(control_handle),
8024 tx_id: header.tx_id,
8025 },
8026 })
8027 }
8028 0x77d19a494b78ba8c => {
8029 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
8030 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
8031 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
8032 let control_handle = BufferCollectionTokenControlHandle {
8033 inner: this.inner.clone(),
8034 };
8035 Ok(BufferCollectionTokenRequest::GetBufferCollectionId {
8036 responder: BufferCollectionTokenGetBufferCollectionIdResponder {
8037 control_handle: std::mem::ManuallyDrop::new(control_handle),
8038 tx_id: header.tx_id,
8039 },
8040 })
8041 }
8042 0x22dd3ea514eeffe1 => {
8043 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8044 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
8045 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
8046 let control_handle = BufferCollectionTokenControlHandle {
8047 inner: this.inner.clone(),
8048 };
8049 Ok(BufferCollectionTokenRequest::SetWeak {
8050 control_handle,
8051 })
8052 }
8053 0x38a44fc4d7724be9 => {
8054 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8055 let mut req = fidl::new_empty!(NodeSetWeakOkRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8056 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetWeakOkRequest>(&header, _body_bytes, handles, &mut req)?;
8057 let control_handle = BufferCollectionTokenControlHandle {
8058 inner: this.inner.clone(),
8059 };
8060 Ok(BufferCollectionTokenRequest::SetWeakOk {payload: req,
8061 control_handle,
8062 })
8063 }
8064 0x3f22f2a293d3cdac => {
8065 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8066 let mut req = fidl::new_empty!(NodeAttachNodeTrackingRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8067 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeAttachNodeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
8068 let control_handle = BufferCollectionTokenControlHandle {
8069 inner: this.inner.clone(),
8070 };
8071 Ok(BufferCollectionTokenRequest::AttachNodeTracking {payload: req,
8072 control_handle,
8073 })
8074 }
8075 0x1c1af9919d1ca45c => {
8076 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
8077 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8078 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateSyncRequest>(&header, _body_bytes, handles, &mut req)?;
8079 let control_handle = BufferCollectionTokenControlHandle {
8080 inner: this.inner.clone(),
8081 };
8082 Ok(BufferCollectionTokenRequest::DuplicateSync {payload: req,
8083 responder: BufferCollectionTokenDuplicateSyncResponder {
8084 control_handle: std::mem::ManuallyDrop::new(control_handle),
8085 tx_id: header.tx_id,
8086 },
8087 })
8088 }
8089 0x73e78f92ee7fb887 => {
8090 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8091 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8092 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateRequest>(&header, _body_bytes, handles, &mut req)?;
8093 let control_handle = BufferCollectionTokenControlHandle {
8094 inner: this.inner.clone(),
8095 };
8096 Ok(BufferCollectionTokenRequest::Duplicate {payload: req,
8097 control_handle,
8098 })
8099 }
8100 0x228acf979254df8b => {
8101 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8102 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
8103 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
8104 let control_handle = BufferCollectionTokenControlHandle {
8105 inner: this.inner.clone(),
8106 };
8107 Ok(BufferCollectionTokenRequest::SetDispensable {
8108 control_handle,
8109 })
8110 }
8111 0x30f8d48e77bd36f2 => {
8112 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8113 let mut req = fidl::new_empty!(BufferCollectionTokenCreateBufferCollectionTokenGroupRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8114 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(&header, _body_bytes, handles, &mut req)?;
8115 let control_handle = BufferCollectionTokenControlHandle {
8116 inner: this.inner.clone(),
8117 };
8118 Ok(BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {payload: req,
8119 control_handle,
8120 })
8121 }
8122 _ if header.tx_id == 0 && header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
8123 Ok(BufferCollectionTokenRequest::_UnknownMethod {
8124 ordinal: header.ordinal,
8125 control_handle: BufferCollectionTokenControlHandle { inner: this.inner.clone() },
8126 method_type: fidl::MethodType::OneWay,
8127 })
8128 }
8129 _ if header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
8130 this.inner.send_framework_err(
8131 fidl::encoding::FrameworkErr::UnknownMethod,
8132 header.tx_id,
8133 header.ordinal,
8134 header.dynamic_flags(),
8135 (bytes, handles),
8136 )?;
8137 Ok(BufferCollectionTokenRequest::_UnknownMethod {
8138 ordinal: header.ordinal,
8139 control_handle: BufferCollectionTokenControlHandle { inner: this.inner.clone() },
8140 method_type: fidl::MethodType::TwoWay,
8141 })
8142 }
8143 _ => Err(fidl::Error::UnknownOrdinal {
8144 ordinal: header.ordinal,
8145 protocol_name: <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
8146 }),
8147 }))
8148 },
8149 )
8150 }
8151}
8152
8153/// A [`fuchsia.sysmem2/BufferCollectionToken`] is not a buffer collection, but
8154/// rather is a way to identify a specific potential shared buffer collection,
8155/// and a way to distribute that potential shared buffer collection to
8156/// additional participants prior to the buffer collection allocating any
8157/// buffers.
8158///
8159/// Epitaphs are not used in this protocol.
8160///
8161/// We use a channel for the `BufferCollectionToken` instead of a single
8162/// `eventpair` (pair) because this way we can detect error conditions like a
8163/// participant failing mid-create.
8164#[derive(Debug)]
8165pub enum BufferCollectionTokenRequest {
8166 /// Ensure that previous messages have been received server side. This is
8167 /// particularly useful after previous messages that created new tokens,
8168 /// because a token must be known to the sysmem server before sending the
8169 /// token to another participant.
8170 ///
8171 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
8172 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
8173 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
8174 /// to mitigate the possibility of a hostile/fake
8175 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
8176 /// Another way is to pass the token to
8177 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
8178 /// the token as part of exchanging it for a
8179 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
8180 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
8181 /// of stalling.
8182 ///
8183 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
8184 /// and then starting and completing a `Sync`, it's then safe to send the
8185 /// `BufferCollectionToken` client ends to other participants knowing the
8186 /// server will recognize the tokens when they're sent by the other
8187 /// participants to sysmem in a
8188 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
8189 /// efficient way to create tokens while avoiding unnecessary round trips.
8190 ///
8191 /// Other options include waiting for each
8192 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
8193 /// individually (using separate call to `Sync` after each), or calling
8194 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
8195 /// converted to a `BufferCollection` via
8196 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
8197 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
8198 /// the sync step and can create multiple tokens at once.
8199 Sync { responder: BufferCollectionTokenSyncResponder },
8200 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
8201 ///
8202 /// Normally a participant will convert a `BufferCollectionToken` into a
8203 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
8204 /// `Release` via the token (and then close the channel immediately or
8205 /// shortly later in response to server closing the server end), which
8206 /// avoids causing buffer collection failure. Without a prior `Release`,
8207 /// closing the `BufferCollectionToken` client end will cause buffer
8208 /// collection failure.
8209 ///
8210 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
8211 ///
8212 /// By default the server handles unexpected closure of a
8213 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
8214 /// first) by failing the buffer collection. Partly this is to expedite
8215 /// closing VMO handles to reclaim memory when any participant fails. If a
8216 /// participant would like to cleanly close a `BufferCollection` without
8217 /// causing buffer collection failure, the participant can send `Release`
8218 /// before closing the `BufferCollection` client end. The `Release` can
8219 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
8220 /// buffer collection won't require constraints from this node in order to
8221 /// allocate. If after `SetConstraints`, the constraints are retained and
8222 /// aggregated, despite the lack of `BufferCollection` connection at the
8223 /// time of constraints aggregation.
8224 ///
8225 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
8226 ///
8227 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
8228 /// end (without `Release` first) will trigger failure of the buffer
8229 /// collection. To close a `BufferCollectionTokenGroup` channel without
8230 /// failing the buffer collection, ensure that AllChildrenPresent() has been
8231 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
8232 /// client end.
8233 ///
8234 /// If `Release` occurs before
8235 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
8236 /// buffer collection will fail (triggered by reception of `Release` without
8237 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
8238 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
8239 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
8240 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
8241 /// close requires `AllChildrenPresent` (if not already sent), then
8242 /// `Release`, then close client end.
8243 ///
8244 /// If `Release` occurs after `AllChildrenPresent`, the children and all
8245 /// their constraints remain intact (just as they would if the
8246 /// `BufferCollectionTokenGroup` channel had remained open), and the client
8247 /// end close doesn't trigger buffer collection failure.
8248 ///
8249 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
8250 ///
8251 /// For brevity, the per-channel-protocol paragraphs above ignore the
8252 /// separate failure domain created by
8253 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
8254 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
8255 /// unexpectedly closes (without `Release` first) and that client end is
8256 /// under a failure domain, instead of failing the whole buffer collection,
8257 /// the failure domain is failed, but the buffer collection itself is
8258 /// isolated from failure of the failure domain. Such failure domains can be
8259 /// nested, in which case only the inner-most failure domain in which the
8260 /// `Node` resides fails.
8261 Release { control_handle: BufferCollectionTokenControlHandle },
8262 /// Set a name for VMOs in this buffer collection.
8263 ///
8264 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
8265 /// will be truncated to fit. The name of the vmo will be suffixed with the
8266 /// buffer index within the collection (if the suffix fits within
8267 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
8268 /// listed in the inspect data.
8269 ///
8270 /// The name only affects VMOs allocated after the name is set; this call
8271 /// does not rename existing VMOs. If multiple clients set different names
8272 /// then the larger priority value will win. Setting a new name with the
8273 /// same priority as a prior name doesn't change the name.
8274 ///
8275 /// All table fields are currently required.
8276 ///
8277 /// + request `priority` The name is only set if this is the first `SetName`
8278 /// or if `priority` is greater than any previous `priority` value in
8279 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
8280 /// + request `name` The name for VMOs created under this buffer collection.
8281 SetName { payload: NodeSetNameRequest, control_handle: BufferCollectionTokenControlHandle },
8282 /// Set information about the current client that can be used by sysmem to
8283 /// help diagnose leaking memory and allocation stalls waiting for a
8284 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
8285 ///
8286 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
8287 /// `Node`(s) derived from this `Node`, unless overriden by
8288 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
8289 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
8290 ///
8291 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
8292 /// `Allocator` is the most efficient way to ensure that all
8293 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
8294 /// set, and is also more efficient than separately sending the same debug
8295 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
8296 /// created [`fuchsia.sysmem2/Node`].
8297 ///
8298 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
8299 /// indicate which client is closing their channel first, leading to subtree
8300 /// failure (which can be normal if the purpose of the subtree is over, but
8301 /// if happening earlier than expected, the client-channel-specific name can
8302 /// help diagnose where the failure is first coming from, from sysmem's
8303 /// point of view).
8304 ///
8305 /// All table fields are currently required.
8306 ///
8307 /// + request `name` This can be an arbitrary string, but the current
8308 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
8309 /// + request `id` This can be an arbitrary id, but the current process ID
8310 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
8311 SetDebugClientInfo {
8312 payload: NodeSetDebugClientInfoRequest,
8313 control_handle: BufferCollectionTokenControlHandle,
8314 },
8315 /// Sysmem logs a warning if sysmem hasn't seen
8316 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
8317 /// within 5 seconds after creation of a new collection.
8318 ///
8319 /// Clients can call this method to change when the log is printed. If
8320 /// multiple client set the deadline, it's unspecified which deadline will
8321 /// take effect.
8322 ///
8323 /// In most cases the default works well.
8324 ///
8325 /// All table fields are currently required.
8326 ///
8327 /// + request `deadline` The time at which sysmem will start trying to log
8328 /// the warning, unless all constraints are with sysmem by then.
8329 SetDebugTimeoutLogDeadline {
8330 payload: NodeSetDebugTimeoutLogDeadlineRequest,
8331 control_handle: BufferCollectionTokenControlHandle,
8332 },
8333 /// This enables verbose logging for the buffer collection.
8334 ///
8335 /// Verbose logging includes constraints set via
8336 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
8337 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
8338 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
8339 /// the tree of `Node`(s).
8340 ///
8341 /// Normally sysmem prints only a single line complaint when aggregation
8342 /// fails, with just the specific detailed reason that aggregation failed,
8343 /// with little surrounding context. While this is often enough to diagnose
8344 /// a problem if only a small change was made and everything was working
8345 /// before the small change, it's often not particularly helpful for getting
8346 /// a new buffer collection to work for the first time. Especially with
8347 /// more complex trees of nodes, involving things like
8348 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
8349 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
8350 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
8351 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
8352 /// looks like and why it's failing a logical allocation, or why a tree or
8353 /// subtree is failing sooner than expected.
8354 ///
8355 /// The intent of the extra logging is to be acceptable from a performance
8356 /// point of view, under the assumption that verbose logging is only enabled
8357 /// on a low number of buffer collections. If we're not tracking down a bug,
8358 /// we shouldn't send this message.
8359 SetVerboseLogging { control_handle: BufferCollectionTokenControlHandle },
8360 /// This gets a handle that can be used as a parameter to
8361 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
8362 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
8363 /// client obtained this handle from this `Node`.
8364 ///
8365 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
8366 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
8367 /// despite the two calls typically being on different channels.
8368 ///
8369 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
8370 ///
8371 /// All table fields are currently required.
8372 ///
8373 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
8374 /// different `Node` channel, to prove that the client obtained the handle
8375 /// from this `Node`.
8376 GetNodeRef { responder: BufferCollectionTokenGetNodeRefResponder },
8377 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
8378 /// rooted at a different child token of a common parent
8379 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
8380 /// passed-in `node_ref`.
8381 ///
8382 /// This call is for assisting with admission control de-duplication, and
8383 /// with debugging.
8384 ///
8385 /// The `node_ref` must be obtained using
8386 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
8387 ///
8388 /// The `node_ref` can be a duplicated handle; it's not necessary to call
8389 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
8390 ///
8391 /// If a calling token may not actually be a valid token at all due to a
8392 /// potentially hostile/untrusted provider of the token, call
8393 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
8394 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
8395 /// never responds due to a calling token not being a real token (not really
8396 /// talking to sysmem). Another option is to call
8397 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
8398 /// which also validates the token along with converting it to a
8399 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
8400 ///
8401 /// All table fields are currently required.
8402 ///
8403 /// - response `is_alternate`
8404 /// - true: The first parent node in common between the calling node and
8405 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
8406 /// that the calling `Node` and the `node_ref` `Node` will not have both
8407 /// their constraints apply - rather sysmem will choose one or the other
8408 /// of the constraints - never both. This is because only one child of
8409 /// a `BufferCollectionTokenGroup` is selected during logical
8410 /// allocation, with only that one child's subtree contributing to
8411 /// constraints aggregation.
8412 /// - false: The first parent node in common between the calling `Node`
8413 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
8414 /// Currently, this means the first parent node in common is a
8415 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
8416 /// `Release`ed). This means that the calling `Node` and the `node_ref`
8417 /// `Node` may have both their constraints apply during constraints
8418 /// aggregation of the logical allocation, if both `Node`(s) are
8419 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
8420 /// this case, there is no `BufferCollectionTokenGroup` that will
8421 /// directly prevent the two `Node`(s) from both being selected and
8422 /// their constraints both aggregated, but even when false, one or both
8423 /// `Node`(s) may still be eliminated from consideration if one or both
8424 /// `Node`(s) has a direct or indirect parent
8425 /// `BufferCollectionTokenGroup` which selects a child subtree other
8426 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
8427 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
8428 /// associated with the same buffer collection as the calling `Node`.
8429 /// Another reason for this error is if the `node_ref` is an
8430 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
8431 /// a real `node_ref` obtained from `GetNodeRef`.
8432 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
8433 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
8434 /// the needed rights expected on a real `node_ref`.
8435 /// * No other failing status codes are returned by this call. However,
8436 /// sysmem may add additional codes in future, so the client should have
8437 /// sensible default handling for any failing status code.
8438 IsAlternateFor {
8439 payload: NodeIsAlternateForRequest,
8440 responder: BufferCollectionTokenIsAlternateForResponder,
8441 },
8442 /// Get the buffer collection ID. This ID is also available from
8443 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
8444 /// within the collection).
8445 ///
8446 /// This call is mainly useful in situations where we can't convey a
8447 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
8448 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
8449 /// handle, which can be joined back up with a `BufferCollection` client end
8450 /// that was created via a different path. Prefer to convey a
8451 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
8452 ///
8453 /// Trusting a `buffer_collection_id` value from a source other than sysmem
8454 /// is analogous to trusting a koid value from a source other than zircon.
8455 /// Both should be avoided unless really necessary, and both require
8456 /// caution. In some situations it may be reasonable to refer to a
8457 /// pre-established `BufferCollection` by `buffer_collection_id` via a
8458 /// protocol for efficiency reasons, but an incoming value purporting to be
8459 /// a `buffer_collection_id` is not sufficient alone to justify granting the
8460 /// sender of the `buffer_collection_id` any capability. The sender must
8461 /// first prove to a receiver that the sender has/had a VMO or has/had a
8462 /// `BufferCollectionToken` to the same collection by sending a handle that
8463 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
8464 /// `buffer_collection_id` value. The receiver should take care to avoid
8465 /// assuming that a sender had a `BufferCollectionToken` in cases where the
8466 /// sender has only proven that the sender had a VMO.
8467 ///
8468 /// - response `buffer_collection_id` This ID is unique per buffer
8469 /// collection per boot. Each buffer is uniquely identified by the
8470 /// `buffer_collection_id` and `buffer_index` together.
8471 GetBufferCollectionId { responder: BufferCollectionTokenGetBufferCollectionIdResponder },
8472 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
8473 /// created after this message to weak, which means that a client's `Node`
8474 /// client end (or a child created after this message) is not alone
8475 /// sufficient to keep allocated VMOs alive.
8476 ///
8477 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
8478 /// `close_weak_asap`.
8479 ///
8480 /// This message is only permitted before the `Node` becomes ready for
8481 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
8482 /// * `BufferCollectionToken`: any time
8483 /// * `BufferCollection`: before `SetConstraints`
8484 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
8485 ///
8486 /// Currently, no conversion from strong `Node` to weak `Node` after ready
8487 /// for allocation is provided, but a client can simulate that by creating
8488 /// an additional `Node` before allocation and setting that additional
8489 /// `Node` to weak, and then potentially at some point later sending
8490 /// `Release` and closing the client end of the client's strong `Node`, but
8491 /// keeping the client's weak `Node`.
8492 ///
8493 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
8494 /// collection failure (all `Node` client end(s) will see
8495 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
8496 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
8497 /// this situation until all `Node`(s) are ready for allocation. For initial
8498 /// allocation to succeed, at least one strong `Node` is required to exist
8499 /// at allocation time, but after that client receives VMO handles, that
8500 /// client can `BufferCollection.Release` and close the client end without
8501 /// causing this type of failure.
8502 ///
8503 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
8504 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
8505 /// separately as appropriate.
8506 SetWeak { control_handle: BufferCollectionTokenControlHandle },
8507 /// This indicates to sysmem that the client is prepared to pay attention to
8508 /// `close_weak_asap`.
8509 ///
8510 /// If sent, this message must be before
8511 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
8512 ///
8513 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
8514 /// send this message before `WaitForAllBuffersAllocated`, or a parent
8515 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
8516 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
8517 /// trigger buffer collection failure.
8518 ///
8519 /// This message is necessary because weak sysmem VMOs have not always been
8520 /// a thing, so older clients are not aware of the need to pay attention to
8521 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
8522 /// sysmem weak VMO handles asap. By having this message and requiring
8523 /// participants to indicate their acceptance of this aspect of the overall
8524 /// protocol, we avoid situations where an older client is delivered a weak
8525 /// VMO without any way for sysmem to get that VMO to close quickly later
8526 /// (and on a per-buffer basis).
8527 ///
8528 /// A participant that doesn't handle `close_weak_asap` and also doesn't
8529 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
8530 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
8531 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
8532 /// same participant has a child/delegate which does retrieve VMOs, that
8533 /// child/delegate will need to send `SetWeakOk` before
8534 /// `WaitForAllBuffersAllocated`.
8535 ///
8536 /// + request `for_child_nodes_also` If present and true, this means direct
8537 /// child nodes of this node created after this message plus all
8538 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
8539 /// those nodes. Any child node of this node that was created before this
8540 /// message is not included. This setting is "sticky" in the sense that a
8541 /// subsequent `SetWeakOk` without this bool set to true does not reset
8542 /// the server-side bool. If this creates a problem for a participant, a
8543 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
8544 /// tokens instead, as appropriate. A participant should only set
8545 /// `for_child_nodes_also` true if the participant can really promise to
8546 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
8547 /// weak VMO handles held by participants holding the corresponding child
8548 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
8549 /// which are using sysmem(1) can be weak, despite the clients of those
8550 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
8551 /// direct way to find out about `close_weak_asap`. This only applies to
8552 /// descendents of this `Node` which are using sysmem(1), not to this
8553 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
8554 /// token, which will fail allocation unless an ancestor of this `Node`
8555 /// specified `for_child_nodes_also` true.
8556 SetWeakOk { payload: NodeSetWeakOkRequest, control_handle: BufferCollectionTokenControlHandle },
8557 /// The server_end will be closed after this `Node` and any child nodes have
8558 /// have released their buffer counts, making those counts available for
8559 /// reservation by a different `Node` via
8560 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
8561 ///
8562 /// The `Node` buffer counts may not be released until the entire tree of
8563 /// `Node`(s) is closed or failed, because
8564 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
8565 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
8566 /// `Node` buffer counts remain reserved until the orphaned node is later
8567 /// cleaned up.
8568 ///
8569 /// If the `Node` exceeds a fairly large number of attached eventpair server
8570 /// ends, a log message will indicate this and the `Node` (and the
8571 /// appropriate) sub-tree will fail.
8572 ///
8573 /// The `server_end` will remain open when
8574 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
8575 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
8576 /// [`fuchsia.sysmem2/BufferCollection`].
8577 ///
8578 /// This message can also be used with a
8579 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
8580 AttachNodeTracking {
8581 payload: NodeAttachNodeTrackingRequest,
8582 control_handle: BufferCollectionTokenControlHandle,
8583 },
8584 /// Create additional [`fuchsia.sysmem2/BufferCollectionToken`](s) from this
8585 /// one, referring to the same buffer collection.
8586 ///
8587 /// The created tokens are children of this token in the
8588 /// [`fuchsia.sysmem2/Node`] heirarchy.
8589 ///
8590 /// This method can be used to add more participants, by transferring the
8591 /// newly created tokens to additional participants.
8592 ///
8593 /// A new token will be returned for each entry in the
8594 /// `rights_attenuation_masks` array.
8595 ///
8596 /// If the called token may not actually be a valid token due to a
8597 /// potentially hostile/untrusted provider of the token, consider using
8598 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
8599 /// instead of potentially getting stuck indefinitely if
8600 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] never responds
8601 /// due to the calling token not being a real token.
8602 ///
8603 /// In contrast to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], no
8604 /// separate [`fuchsia.sysmem2/Node.Sync`] is needed after calling this
8605 /// method, because the sync step is included in this call, at the cost of a
8606 /// round trip during this call.
8607 ///
8608 /// All tokens must be turned in to sysmem via
8609 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
8610 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
8611 /// successfully allocate buffers (or to logically allocate buffers in the
8612 /// case of subtrees involving
8613 /// [`fuchsia.sysmem2/BufferCollectionToken.AttachToken`]).
8614 ///
8615 /// All table fields are currently required.
8616 ///
8617 /// + request `rights_attenuation_mask` In each entry of
8618 /// `rights_attenuation_masks`, rights bits that are zero will be absent
8619 /// in the buffer VMO rights obtainable via the corresponding returned
8620 /// token. This allows an initiator or intermediary participant to
8621 /// attenuate the rights available to a participant. This does not allow a
8622 /// participant to gain rights that the participant doesn't already have.
8623 /// The value `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no
8624 /// attenuation should be applied.
8625 /// - response `tokens` The client ends of each newly created token.
8626 DuplicateSync {
8627 payload: BufferCollectionTokenDuplicateSyncRequest,
8628 responder: BufferCollectionTokenDuplicateSyncResponder,
8629 },
8630 /// Create an additional [`fuchsia.sysmem2/BufferCollectionToken`] from this
8631 /// one, referring to the same buffer collection.
8632 ///
8633 /// The created token is a child of this token in the
8634 /// [`fuchsia.sysmem2/Node`] heirarchy.
8635 ///
8636 /// This method can be used to add a participant, by transferring the newly
8637 /// created token to another participant.
8638 ///
8639 /// This one-way message can be used instead of the two-way
8640 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] FIDL call in
8641 /// performance sensitive cases where it would be undesireable to wait for
8642 /// sysmem to respond to
8643 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] or when the
8644 /// client code isn't structured to make it easy to duplicate all the needed
8645 /// tokens at once.
8646 ///
8647 /// After sending one or more `Duplicate` messages, and before sending the
8648 /// newly created child tokens to other participants (or to other
8649 /// [`fuchsia.sysmem2/Allocator`] channels), the client must send a
8650 /// [`fuchsia.sysmem2/Node.Sync`] and wait for the `Sync` response. The
8651 /// `Sync` call can be made on the token, or on the `BufferCollection`
8652 /// obtained by passing this token to `BindSharedCollection`. Either will
8653 /// ensure that the server knows about the tokens created via `Duplicate`
8654 /// before the other participant sends the token to the server via separate
8655 /// `Allocator` channel.
8656 ///
8657 /// All tokens must be turned in via
8658 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
8659 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
8660 /// successfully allocate buffers.
8661 ///
8662 /// All table fields are currently required.
8663 ///
8664 /// + request `rights_attenuation_mask` The rights bits that are zero in
8665 /// this mask will be absent in the buffer VMO rights obtainable via the
8666 /// client end of `token_request`. This allows an initiator or
8667 /// intermediary participant to attenuate the rights available to a
8668 /// delegate participant. This does not allow a participant to gain rights
8669 /// that the participant doesn't already have. The value
8670 /// `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no attenuation
8671 /// should be applied.
8672 /// + These values for rights_attenuation_mask result in no attenuation:
8673 /// + `ZX_RIGHT_SAME_RIGHTS` (preferred)
8674 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is
8675 /// computed)
8676 /// + 0 (deprecated - do not use 0 - an ERROR will go to the log)
8677 /// + request `token_request` is the server end of a `BufferCollectionToken`
8678 /// channel. The client end of this channel acts as another participant in
8679 /// the shared buffer collection.
8680 Duplicate {
8681 payload: BufferCollectionTokenDuplicateRequest,
8682 control_handle: BufferCollectionTokenControlHandle,
8683 },
8684 /// Set this [`fuchsia.sysmem2/BufferCollectionToken`] to dispensable.
8685 ///
8686 /// When the `BufferCollectionToken` is converted to a
8687 /// [`fuchsia.sysmem2/BufferCollection`], the dispensable status applies to
8688 /// the `BufferCollection` also.
8689 ///
8690 /// Normally, if a client closes a [`fuchsia.sysmem2/BufferCollection`]
8691 /// client end without having sent
8692 /// [`fuchsia.sysmem2/BufferCollection.Release`] first, the
8693 /// `BufferCollection` [`fuchisa.sysmem2/Node`] will fail, which also
8694 /// propagates failure to the parent [`fuchsia.sysmem2/Node`] and so on up
8695 /// to the root `Node`, which fails the whole buffer collection. In
8696 /// contrast, a dispensable `Node` can fail after buffers are allocated
8697 /// without causing failure of its parent in the [`fuchsia.sysmem2/Node`]
8698 /// heirarchy.
8699 ///
8700 /// The dispensable `Node` participates in constraints aggregation along
8701 /// with its parent before buffer allocation. If the dispensable `Node`
8702 /// fails before buffers are allocated, the failure propagates to the
8703 /// dispensable `Node`'s parent.
8704 ///
8705 /// After buffers are allocated, failure of the dispensable `Node` (or any
8706 /// child of the dispensable `Node`) does not propagate to the dispensable
8707 /// `Node`'s parent. Failure does propagate from a normal child of a
8708 /// dispensable `Node` to the dispensable `Node`. Failure of a child is
8709 /// blocked from reaching its parent if the child is attached using
8710 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or if the child is
8711 /// dispensable and the failure occurred after allocation.
8712 ///
8713 /// A dispensable `Node` can be used in cases where a participant needs to
8714 /// provide constraints, but after buffers are allocated, the participant
8715 /// can fail without causing buffer collection failure from the parent
8716 /// `Node`'s point of view.
8717 ///
8718 /// In contrast, `BufferCollection.AttachToken` can be used to create a
8719 /// `BufferCollectionToken` which does not participate in constraints
8720 /// aggregation with its parent `Node`, and whose failure at any time does
8721 /// not propagate to its parent `Node`, and whose potential delay providing
8722 /// constraints does not prevent the parent `Node` from completing its
8723 /// buffer allocation.
8724 ///
8725 /// An initiator (creator of the root `Node` using
8726 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`]) may in some
8727 /// scenarios choose to initially use a dispensable `Node` for a first
8728 /// instance of a participant, and then later if the first instance of that
8729 /// participant fails, a new second instance of that participant my be given
8730 /// a `BufferCollectionToken` created with `AttachToken`.
8731 ///
8732 /// Normally a client will `SetDispensable` on a `BufferCollectionToken`
8733 /// shortly before sending the dispensable `BufferCollectionToken` to a
8734 /// delegate participant. Because `SetDispensable` prevents propagation of
8735 /// child `Node` failure to parent `Node`(s), if the client was relying on
8736 /// noticing child failure via failure of the parent `Node` retained by the
8737 /// client, the client may instead need to notice failure via other means.
8738 /// If other means aren't available/convenient, the client can instead
8739 /// retain the dispensable `Node` and create a child `Node` under that to
8740 /// send to the delegate participant, retaining this `Node` in order to
8741 /// notice failure of the subtree rooted at this `Node` via this `Node`'s
8742 /// ZX_CHANNEL_PEER_CLOSED signal, and take whatever action is appropriate
8743 /// (e.g. starting a new instance of the delegate participant and handing it
8744 /// a `BufferCollectionToken` created using
8745 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or propagate failure
8746 /// and clean up in a client-specific way).
8747 ///
8748 /// While it is possible (and potentially useful) to `SetDispensable` on a
8749 /// direct child of a `BufferCollectionTokenGroup` `Node`, it isn't possible
8750 /// to later replace a failed dispensable `Node` that was a direct child of
8751 /// a `BufferCollectionTokenGroup` with a new token using `AttachToken`
8752 /// (since there's no `AttachToken` on a group). Instead, to enable
8753 /// `AttachToken` replacement in this case, create an additional
8754 /// non-dispensable token that's a direct child of the group and make the
8755 /// existing dispensable token a child of the additional token. This way,
8756 /// the additional token that is a direct child of the group has
8757 /// `BufferCollection.AttachToken` which can be used to replace the failed
8758 /// dispensable token.
8759 ///
8760 /// `SetDispensable` on an already-dispensable token is idempotent.
8761 SetDispensable { control_handle: BufferCollectionTokenControlHandle },
8762 /// Create a logical OR among a set of tokens, called a
8763 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
8764 ///
8765 /// Most sysmem clients and many participants don't need to care about this
8766 /// message or about `BufferCollectionTokenGroup`(s). However, in some cases
8767 /// a participant wants to attempt to include one set of delegate
8768 /// participants, but if constraints don't combine successfully that way,
8769 /// fall back to a different (possibly overlapping) set of delegate
8770 /// participants, and/or fall back to a less demanding strategy (in terms of
8771 /// how strict the [`fuchisa.sysmem2/BufferCollectionConstraints`] are,
8772 /// across all involved delegate participants). In such cases, a
8773 /// `BufferCollectionTokenGroup` is useful.
8774 ///
8775 /// A `BufferCollectionTokenGroup` is used to create a 1 of N OR among N
8776 /// child [`fuchsia.sysmem2/BufferCollectionToken`](s). The child tokens
8777 /// which are not selected during aggregation will fail (close), which a
8778 /// potential participant should notice when their `BufferCollection`
8779 /// channel client endpoint sees PEER_CLOSED, allowing the participant to
8780 /// clean up the speculative usage that didn't end up happening (this is
8781 /// simimlar to a normal `BufferCollection` server end closing on failure to
8782 /// allocate a logical buffer collection or later async failure of a buffer
8783 /// collection).
8784 ///
8785 /// See comments on protocol `BufferCollectionTokenGroup`.
8786 ///
8787 /// Any `rights_attenuation_mask` or `AttachToken`/`SetDispensable` to be
8788 /// applied to the whole group can be achieved with a
8789 /// `BufferCollectionToken` for this purpose as a direct parent of the
8790 /// `BufferCollectionTokenGroup`.
8791 ///
8792 /// All table fields are currently required.
8793 ///
8794 /// + request `group_request` The server end of a
8795 /// `BufferCollectionTokenGroup` channel to be served by sysmem.
8796 CreateBufferCollectionTokenGroup {
8797 payload: BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
8798 control_handle: BufferCollectionTokenControlHandle,
8799 },
8800 /// An interaction was received which does not match any known method.
8801 #[non_exhaustive]
8802 _UnknownMethod {
8803 /// Ordinal of the method that was called.
8804 ordinal: u64,
8805 control_handle: BufferCollectionTokenControlHandle,
8806 method_type: fidl::MethodType,
8807 },
8808}
8809
8810impl BufferCollectionTokenRequest {
8811 #[allow(irrefutable_let_patterns)]
8812 pub fn into_sync(self) -> Option<(BufferCollectionTokenSyncResponder)> {
8813 if let BufferCollectionTokenRequest::Sync { responder } = self {
8814 Some((responder))
8815 } else {
8816 None
8817 }
8818 }
8819
8820 #[allow(irrefutable_let_patterns)]
8821 pub fn into_release(self) -> Option<(BufferCollectionTokenControlHandle)> {
8822 if let BufferCollectionTokenRequest::Release { control_handle } = self {
8823 Some((control_handle))
8824 } else {
8825 None
8826 }
8827 }
8828
8829 #[allow(irrefutable_let_patterns)]
8830 pub fn into_set_name(self) -> Option<(NodeSetNameRequest, BufferCollectionTokenControlHandle)> {
8831 if let BufferCollectionTokenRequest::SetName { payload, control_handle } = self {
8832 Some((payload, control_handle))
8833 } else {
8834 None
8835 }
8836 }
8837
8838 #[allow(irrefutable_let_patterns)]
8839 pub fn into_set_debug_client_info(
8840 self,
8841 ) -> Option<(NodeSetDebugClientInfoRequest, BufferCollectionTokenControlHandle)> {
8842 if let BufferCollectionTokenRequest::SetDebugClientInfo { payload, control_handle } = self {
8843 Some((payload, control_handle))
8844 } else {
8845 None
8846 }
8847 }
8848
8849 #[allow(irrefutable_let_patterns)]
8850 pub fn into_set_debug_timeout_log_deadline(
8851 self,
8852 ) -> Option<(NodeSetDebugTimeoutLogDeadlineRequest, BufferCollectionTokenControlHandle)> {
8853 if let BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {
8854 payload,
8855 control_handle,
8856 } = self
8857 {
8858 Some((payload, control_handle))
8859 } else {
8860 None
8861 }
8862 }
8863
8864 #[allow(irrefutable_let_patterns)]
8865 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenControlHandle)> {
8866 if let BufferCollectionTokenRequest::SetVerboseLogging { control_handle } = self {
8867 Some((control_handle))
8868 } else {
8869 None
8870 }
8871 }
8872
8873 #[allow(irrefutable_let_patterns)]
8874 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGetNodeRefResponder)> {
8875 if let BufferCollectionTokenRequest::GetNodeRef { responder } = self {
8876 Some((responder))
8877 } else {
8878 None
8879 }
8880 }
8881
8882 #[allow(irrefutable_let_patterns)]
8883 pub fn into_is_alternate_for(
8884 self,
8885 ) -> Option<(NodeIsAlternateForRequest, BufferCollectionTokenIsAlternateForResponder)> {
8886 if let BufferCollectionTokenRequest::IsAlternateFor { payload, responder } = self {
8887 Some((payload, responder))
8888 } else {
8889 None
8890 }
8891 }
8892
8893 #[allow(irrefutable_let_patterns)]
8894 pub fn into_get_buffer_collection_id(
8895 self,
8896 ) -> Option<(BufferCollectionTokenGetBufferCollectionIdResponder)> {
8897 if let BufferCollectionTokenRequest::GetBufferCollectionId { responder } = self {
8898 Some((responder))
8899 } else {
8900 None
8901 }
8902 }
8903
8904 #[allow(irrefutable_let_patterns)]
8905 pub fn into_set_weak(self) -> Option<(BufferCollectionTokenControlHandle)> {
8906 if let BufferCollectionTokenRequest::SetWeak { control_handle } = self {
8907 Some((control_handle))
8908 } else {
8909 None
8910 }
8911 }
8912
8913 #[allow(irrefutable_let_patterns)]
8914 pub fn into_set_weak_ok(
8915 self,
8916 ) -> Option<(NodeSetWeakOkRequest, BufferCollectionTokenControlHandle)> {
8917 if let BufferCollectionTokenRequest::SetWeakOk { payload, control_handle } = self {
8918 Some((payload, control_handle))
8919 } else {
8920 None
8921 }
8922 }
8923
8924 #[allow(irrefutable_let_patterns)]
8925 pub fn into_attach_node_tracking(
8926 self,
8927 ) -> Option<(NodeAttachNodeTrackingRequest, BufferCollectionTokenControlHandle)> {
8928 if let BufferCollectionTokenRequest::AttachNodeTracking { payload, control_handle } = self {
8929 Some((payload, control_handle))
8930 } else {
8931 None
8932 }
8933 }
8934
8935 #[allow(irrefutable_let_patterns)]
8936 pub fn into_duplicate_sync(
8937 self,
8938 ) -> Option<(
8939 BufferCollectionTokenDuplicateSyncRequest,
8940 BufferCollectionTokenDuplicateSyncResponder,
8941 )> {
8942 if let BufferCollectionTokenRequest::DuplicateSync { payload, responder } = self {
8943 Some((payload, responder))
8944 } else {
8945 None
8946 }
8947 }
8948
8949 #[allow(irrefutable_let_patterns)]
8950 pub fn into_duplicate(
8951 self,
8952 ) -> Option<(BufferCollectionTokenDuplicateRequest, BufferCollectionTokenControlHandle)> {
8953 if let BufferCollectionTokenRequest::Duplicate { payload, control_handle } = self {
8954 Some((payload, control_handle))
8955 } else {
8956 None
8957 }
8958 }
8959
8960 #[allow(irrefutable_let_patterns)]
8961 pub fn into_set_dispensable(self) -> Option<(BufferCollectionTokenControlHandle)> {
8962 if let BufferCollectionTokenRequest::SetDispensable { control_handle } = self {
8963 Some((control_handle))
8964 } else {
8965 None
8966 }
8967 }
8968
8969 #[allow(irrefutable_let_patterns)]
8970 pub fn into_create_buffer_collection_token_group(
8971 self,
8972 ) -> Option<(
8973 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
8974 BufferCollectionTokenControlHandle,
8975 )> {
8976 if let BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {
8977 payload,
8978 control_handle,
8979 } = self
8980 {
8981 Some((payload, control_handle))
8982 } else {
8983 None
8984 }
8985 }
8986
8987 /// Name of the method defined in FIDL
8988 pub fn method_name(&self) -> &'static str {
8989 match *self {
8990 BufferCollectionTokenRequest::Sync { .. } => "sync",
8991 BufferCollectionTokenRequest::Release { .. } => "release",
8992 BufferCollectionTokenRequest::SetName { .. } => "set_name",
8993 BufferCollectionTokenRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
8994 BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline { .. } => {
8995 "set_debug_timeout_log_deadline"
8996 }
8997 BufferCollectionTokenRequest::SetVerboseLogging { .. } => "set_verbose_logging",
8998 BufferCollectionTokenRequest::GetNodeRef { .. } => "get_node_ref",
8999 BufferCollectionTokenRequest::IsAlternateFor { .. } => "is_alternate_for",
9000 BufferCollectionTokenRequest::GetBufferCollectionId { .. } => {
9001 "get_buffer_collection_id"
9002 }
9003 BufferCollectionTokenRequest::SetWeak { .. } => "set_weak",
9004 BufferCollectionTokenRequest::SetWeakOk { .. } => "set_weak_ok",
9005 BufferCollectionTokenRequest::AttachNodeTracking { .. } => "attach_node_tracking",
9006 BufferCollectionTokenRequest::DuplicateSync { .. } => "duplicate_sync",
9007 BufferCollectionTokenRequest::Duplicate { .. } => "duplicate",
9008 BufferCollectionTokenRequest::SetDispensable { .. } => "set_dispensable",
9009 BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup { .. } => {
9010 "create_buffer_collection_token_group"
9011 }
9012 BufferCollectionTokenRequest::_UnknownMethod {
9013 method_type: fidl::MethodType::OneWay,
9014 ..
9015 } => "unknown one-way method",
9016 BufferCollectionTokenRequest::_UnknownMethod {
9017 method_type: fidl::MethodType::TwoWay,
9018 ..
9019 } => "unknown two-way method",
9020 }
9021 }
9022}
9023
9024#[derive(Debug, Clone)]
9025pub struct BufferCollectionTokenControlHandle {
9026 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9027}
9028
9029impl BufferCollectionTokenControlHandle {
9030 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
9031 self.inner.shutdown_with_epitaph(status.into())
9032 }
9033}
9034
9035impl fidl::endpoints::ControlHandle for BufferCollectionTokenControlHandle {
9036 fn shutdown(&self) {
9037 self.inner.shutdown()
9038 }
9039
9040 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
9041 self.inner.shutdown_with_epitaph(status)
9042 }
9043
9044 fn is_closed(&self) -> bool {
9045 self.inner.channel().is_closed()
9046 }
9047 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
9048 self.inner.channel().on_closed()
9049 }
9050
9051 #[cfg(target_os = "fuchsia")]
9052 fn signal_peer(
9053 &self,
9054 clear_mask: zx::Signals,
9055 set_mask: zx::Signals,
9056 ) -> Result<(), zx_status::Status> {
9057 use fidl::Peered;
9058 self.inner.channel().signal_peer(clear_mask, set_mask)
9059 }
9060}
9061
9062impl BufferCollectionTokenControlHandle {}
9063
9064#[must_use = "FIDL methods require a response to be sent"]
9065#[derive(Debug)]
9066pub struct BufferCollectionTokenSyncResponder {
9067 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
9068 tx_id: u32,
9069}
9070
9071/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
9072/// if the responder is dropped without sending a response, so that the client
9073/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9074impl std::ops::Drop for BufferCollectionTokenSyncResponder {
9075 fn drop(&mut self) {
9076 self.control_handle.shutdown();
9077 // Safety: drops once, never accessed again
9078 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9079 }
9080}
9081
9082impl fidl::endpoints::Responder for BufferCollectionTokenSyncResponder {
9083 type ControlHandle = BufferCollectionTokenControlHandle;
9084
9085 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
9086 &self.control_handle
9087 }
9088
9089 fn drop_without_shutdown(mut self) {
9090 // Safety: drops once, never accessed again due to mem::forget
9091 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9092 // Prevent Drop from running (which would shut down the channel)
9093 std::mem::forget(self);
9094 }
9095}
9096
9097impl BufferCollectionTokenSyncResponder {
9098 /// Sends a response to the FIDL transaction.
9099 ///
9100 /// Sets the channel to shutdown if an error occurs.
9101 pub fn send(self) -> Result<(), fidl::Error> {
9102 let _result = self.send_raw();
9103 if _result.is_err() {
9104 self.control_handle.shutdown();
9105 }
9106 self.drop_without_shutdown();
9107 _result
9108 }
9109
9110 /// Similar to "send" but does not shutdown the channel if an error occurs.
9111 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
9112 let _result = self.send_raw();
9113 self.drop_without_shutdown();
9114 _result
9115 }
9116
9117 fn send_raw(&self) -> Result<(), fidl::Error> {
9118 self.control_handle.inner.send::<fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>>(
9119 fidl::encoding::Flexible::new(()),
9120 self.tx_id,
9121 0x11ac2555cf575b54,
9122 fidl::encoding::DynamicFlags::FLEXIBLE,
9123 )
9124 }
9125}
9126
9127#[must_use = "FIDL methods require a response to be sent"]
9128#[derive(Debug)]
9129pub struct BufferCollectionTokenGetNodeRefResponder {
9130 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
9131 tx_id: u32,
9132}
9133
9134/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
9135/// if the responder is dropped without sending a response, so that the client
9136/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9137impl std::ops::Drop for BufferCollectionTokenGetNodeRefResponder {
9138 fn drop(&mut self) {
9139 self.control_handle.shutdown();
9140 // Safety: drops once, never accessed again
9141 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9142 }
9143}
9144
9145impl fidl::endpoints::Responder for BufferCollectionTokenGetNodeRefResponder {
9146 type ControlHandle = BufferCollectionTokenControlHandle;
9147
9148 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
9149 &self.control_handle
9150 }
9151
9152 fn drop_without_shutdown(mut self) {
9153 // Safety: drops once, never accessed again due to mem::forget
9154 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9155 // Prevent Drop from running (which would shut down the channel)
9156 std::mem::forget(self);
9157 }
9158}
9159
9160impl BufferCollectionTokenGetNodeRefResponder {
9161 /// Sends a response to the FIDL transaction.
9162 ///
9163 /// Sets the channel to shutdown if an error occurs.
9164 pub fn send(self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
9165 let _result = self.send_raw(payload);
9166 if _result.is_err() {
9167 self.control_handle.shutdown();
9168 }
9169 self.drop_without_shutdown();
9170 _result
9171 }
9172
9173 /// Similar to "send" but does not shutdown the channel if an error occurs.
9174 pub fn send_no_shutdown_on_err(
9175 self,
9176 mut payload: NodeGetNodeRefResponse,
9177 ) -> Result<(), fidl::Error> {
9178 let _result = self.send_raw(payload);
9179 self.drop_without_shutdown();
9180 _result
9181 }
9182
9183 fn send_raw(&self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
9184 self.control_handle.inner.send::<fidl::encoding::FlexibleType<NodeGetNodeRefResponse>>(
9185 fidl::encoding::Flexible::new(&mut payload),
9186 self.tx_id,
9187 0x5b3d0e51614df053,
9188 fidl::encoding::DynamicFlags::FLEXIBLE,
9189 )
9190 }
9191}
9192
9193#[must_use = "FIDL methods require a response to be sent"]
9194#[derive(Debug)]
9195pub struct BufferCollectionTokenIsAlternateForResponder {
9196 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
9197 tx_id: u32,
9198}
9199
9200/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
9201/// if the responder is dropped without sending a response, so that the client
9202/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9203impl std::ops::Drop for BufferCollectionTokenIsAlternateForResponder {
9204 fn drop(&mut self) {
9205 self.control_handle.shutdown();
9206 // Safety: drops once, never accessed again
9207 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9208 }
9209}
9210
9211impl fidl::endpoints::Responder for BufferCollectionTokenIsAlternateForResponder {
9212 type ControlHandle = BufferCollectionTokenControlHandle;
9213
9214 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
9215 &self.control_handle
9216 }
9217
9218 fn drop_without_shutdown(mut self) {
9219 // Safety: drops once, never accessed again due to mem::forget
9220 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9221 // Prevent Drop from running (which would shut down the channel)
9222 std::mem::forget(self);
9223 }
9224}
9225
9226impl BufferCollectionTokenIsAlternateForResponder {
9227 /// Sends a response to the FIDL transaction.
9228 ///
9229 /// Sets the channel to shutdown if an error occurs.
9230 pub fn send(
9231 self,
9232 mut result: Result<&NodeIsAlternateForResponse, Error>,
9233 ) -> Result<(), fidl::Error> {
9234 let _result = self.send_raw(result);
9235 if _result.is_err() {
9236 self.control_handle.shutdown();
9237 }
9238 self.drop_without_shutdown();
9239 _result
9240 }
9241
9242 /// Similar to "send" but does not shutdown the channel if an error occurs.
9243 pub fn send_no_shutdown_on_err(
9244 self,
9245 mut result: Result<&NodeIsAlternateForResponse, Error>,
9246 ) -> Result<(), fidl::Error> {
9247 let _result = self.send_raw(result);
9248 self.drop_without_shutdown();
9249 _result
9250 }
9251
9252 fn send_raw(
9253 &self,
9254 mut result: Result<&NodeIsAlternateForResponse, Error>,
9255 ) -> Result<(), fidl::Error> {
9256 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
9257 NodeIsAlternateForResponse,
9258 Error,
9259 >>(
9260 fidl::encoding::FlexibleResult::new(result),
9261 self.tx_id,
9262 0x3a58e00157e0825,
9263 fidl::encoding::DynamicFlags::FLEXIBLE,
9264 )
9265 }
9266}
9267
9268#[must_use = "FIDL methods require a response to be sent"]
9269#[derive(Debug)]
9270pub struct BufferCollectionTokenGetBufferCollectionIdResponder {
9271 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
9272 tx_id: u32,
9273}
9274
9275/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
9276/// if the responder is dropped without sending a response, so that the client
9277/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9278impl std::ops::Drop for BufferCollectionTokenGetBufferCollectionIdResponder {
9279 fn drop(&mut self) {
9280 self.control_handle.shutdown();
9281 // Safety: drops once, never accessed again
9282 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9283 }
9284}
9285
9286impl fidl::endpoints::Responder for BufferCollectionTokenGetBufferCollectionIdResponder {
9287 type ControlHandle = BufferCollectionTokenControlHandle;
9288
9289 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
9290 &self.control_handle
9291 }
9292
9293 fn drop_without_shutdown(mut self) {
9294 // Safety: drops once, never accessed again due to mem::forget
9295 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9296 // Prevent Drop from running (which would shut down the channel)
9297 std::mem::forget(self);
9298 }
9299}
9300
9301impl BufferCollectionTokenGetBufferCollectionIdResponder {
9302 /// Sends a response to the FIDL transaction.
9303 ///
9304 /// Sets the channel to shutdown if an error occurs.
9305 pub fn send(self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
9306 let _result = self.send_raw(payload);
9307 if _result.is_err() {
9308 self.control_handle.shutdown();
9309 }
9310 self.drop_without_shutdown();
9311 _result
9312 }
9313
9314 /// Similar to "send" but does not shutdown the channel if an error occurs.
9315 pub fn send_no_shutdown_on_err(
9316 self,
9317 mut payload: &NodeGetBufferCollectionIdResponse,
9318 ) -> Result<(), fidl::Error> {
9319 let _result = self.send_raw(payload);
9320 self.drop_without_shutdown();
9321 _result
9322 }
9323
9324 fn send_raw(&self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
9325 self.control_handle
9326 .inner
9327 .send::<fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>>(
9328 fidl::encoding::Flexible::new(payload),
9329 self.tx_id,
9330 0x77d19a494b78ba8c,
9331 fidl::encoding::DynamicFlags::FLEXIBLE,
9332 )
9333 }
9334}
9335
9336#[must_use = "FIDL methods require a response to be sent"]
9337#[derive(Debug)]
9338pub struct BufferCollectionTokenDuplicateSyncResponder {
9339 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
9340 tx_id: u32,
9341}
9342
9343/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
9344/// if the responder is dropped without sending a response, so that the client
9345/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9346impl std::ops::Drop for BufferCollectionTokenDuplicateSyncResponder {
9347 fn drop(&mut self) {
9348 self.control_handle.shutdown();
9349 // Safety: drops once, never accessed again
9350 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9351 }
9352}
9353
9354impl fidl::endpoints::Responder for BufferCollectionTokenDuplicateSyncResponder {
9355 type ControlHandle = BufferCollectionTokenControlHandle;
9356
9357 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
9358 &self.control_handle
9359 }
9360
9361 fn drop_without_shutdown(mut self) {
9362 // Safety: drops once, never accessed again due to mem::forget
9363 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9364 // Prevent Drop from running (which would shut down the channel)
9365 std::mem::forget(self);
9366 }
9367}
9368
9369impl BufferCollectionTokenDuplicateSyncResponder {
9370 /// Sends a response to the FIDL transaction.
9371 ///
9372 /// Sets the channel to shutdown if an error occurs.
9373 pub fn send(
9374 self,
9375 mut payload: BufferCollectionTokenDuplicateSyncResponse,
9376 ) -> Result<(), fidl::Error> {
9377 let _result = self.send_raw(payload);
9378 if _result.is_err() {
9379 self.control_handle.shutdown();
9380 }
9381 self.drop_without_shutdown();
9382 _result
9383 }
9384
9385 /// Similar to "send" but does not shutdown the channel if an error occurs.
9386 pub fn send_no_shutdown_on_err(
9387 self,
9388 mut payload: BufferCollectionTokenDuplicateSyncResponse,
9389 ) -> Result<(), fidl::Error> {
9390 let _result = self.send_raw(payload);
9391 self.drop_without_shutdown();
9392 _result
9393 }
9394
9395 fn send_raw(
9396 &self,
9397 mut payload: BufferCollectionTokenDuplicateSyncResponse,
9398 ) -> Result<(), fidl::Error> {
9399 self.control_handle.inner.send::<fidl::encoding::FlexibleType<
9400 BufferCollectionTokenDuplicateSyncResponse,
9401 >>(
9402 fidl::encoding::Flexible::new(&mut payload),
9403 self.tx_id,
9404 0x1c1af9919d1ca45c,
9405 fidl::encoding::DynamicFlags::FLEXIBLE,
9406 )
9407 }
9408}
9409
9410#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
9411pub struct BufferCollectionTokenGroupMarker;
9412
9413impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenGroupMarker {
9414 type Proxy = BufferCollectionTokenGroupProxy;
9415 type RequestStream = BufferCollectionTokenGroupRequestStream;
9416 #[cfg(target_os = "fuchsia")]
9417 type SynchronousProxy = BufferCollectionTokenGroupSynchronousProxy;
9418
9419 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionTokenGroup";
9420}
9421
9422pub trait BufferCollectionTokenGroupProxyInterface: Send + Sync {
9423 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
9424 fn r#sync(&self) -> Self::SyncResponseFut;
9425 fn r#release(&self) -> Result<(), fidl::Error>;
9426 fn r#set_name(&self, payload: &NodeSetNameRequest) -> Result<(), fidl::Error>;
9427 fn r#set_debug_client_info(
9428 &self,
9429 payload: &NodeSetDebugClientInfoRequest,
9430 ) -> Result<(), fidl::Error>;
9431 fn r#set_debug_timeout_log_deadline(
9432 &self,
9433 payload: &NodeSetDebugTimeoutLogDeadlineRequest,
9434 ) -> Result<(), fidl::Error>;
9435 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
9436 type GetNodeRefResponseFut: std::future::Future<Output = Result<NodeGetNodeRefResponse, fidl::Error>>
9437 + Send;
9438 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
9439 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
9440 + Send;
9441 fn r#is_alternate_for(
9442 &self,
9443 payload: NodeIsAlternateForRequest,
9444 ) -> Self::IsAlternateForResponseFut;
9445 type GetBufferCollectionIdResponseFut: std::future::Future<Output = Result<NodeGetBufferCollectionIdResponse, fidl::Error>>
9446 + Send;
9447 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut;
9448 fn r#set_weak(&self) -> Result<(), fidl::Error>;
9449 fn r#set_weak_ok(&self, payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error>;
9450 fn r#attach_node_tracking(
9451 &self,
9452 payload: NodeAttachNodeTrackingRequest,
9453 ) -> Result<(), fidl::Error>;
9454 fn r#create_child(
9455 &self,
9456 payload: BufferCollectionTokenGroupCreateChildRequest,
9457 ) -> Result<(), fidl::Error>;
9458 type CreateChildrenSyncResponseFut: std::future::Future<
9459 Output = Result<BufferCollectionTokenGroupCreateChildrenSyncResponse, fidl::Error>,
9460 > + Send;
9461 fn r#create_children_sync(
9462 &self,
9463 payload: &BufferCollectionTokenGroupCreateChildrenSyncRequest,
9464 ) -> Self::CreateChildrenSyncResponseFut;
9465 fn r#all_children_present(&self) -> Result<(), fidl::Error>;
9466}
9467#[derive(Debug)]
9468#[cfg(target_os = "fuchsia")]
9469pub struct BufferCollectionTokenGroupSynchronousProxy {
9470 client: fidl::client::sync::Client,
9471}
9472
9473#[cfg(target_os = "fuchsia")]
9474impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenGroupSynchronousProxy {
9475 type Proxy = BufferCollectionTokenGroupProxy;
9476 type Protocol = BufferCollectionTokenGroupMarker;
9477
9478 fn from_channel(inner: fidl::Channel) -> Self {
9479 Self::new(inner)
9480 }
9481
9482 fn into_channel(self) -> fidl::Channel {
9483 self.client.into_channel()
9484 }
9485
9486 fn as_channel(&self) -> &fidl::Channel {
9487 self.client.as_channel()
9488 }
9489}
9490
9491#[cfg(target_os = "fuchsia")]
9492impl BufferCollectionTokenGroupSynchronousProxy {
9493 pub fn new(channel: fidl::Channel) -> Self {
9494 Self { client: fidl::client::sync::Client::new(channel) }
9495 }
9496
9497 pub fn into_channel(self) -> fidl::Channel {
9498 self.client.into_channel()
9499 }
9500
9501 /// Waits until an event arrives and returns it. It is safe for other
9502 /// threads to make concurrent requests while waiting for an event.
9503 pub fn wait_for_event(
9504 &self,
9505 deadline: zx::MonotonicInstant,
9506 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
9507 BufferCollectionTokenGroupEvent::decode(
9508 self.client.wait_for_event::<BufferCollectionTokenGroupMarker>(deadline)?,
9509 )
9510 }
9511
9512 /// Ensure that previous messages have been received server side. This is
9513 /// particularly useful after previous messages that created new tokens,
9514 /// because a token must be known to the sysmem server before sending the
9515 /// token to another participant.
9516 ///
9517 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
9518 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
9519 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
9520 /// to mitigate the possibility of a hostile/fake
9521 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
9522 /// Another way is to pass the token to
9523 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
9524 /// the token as part of exchanging it for a
9525 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
9526 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
9527 /// of stalling.
9528 ///
9529 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
9530 /// and then starting and completing a `Sync`, it's then safe to send the
9531 /// `BufferCollectionToken` client ends to other participants knowing the
9532 /// server will recognize the tokens when they're sent by the other
9533 /// participants to sysmem in a
9534 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
9535 /// efficient way to create tokens while avoiding unnecessary round trips.
9536 ///
9537 /// Other options include waiting for each
9538 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
9539 /// individually (using separate call to `Sync` after each), or calling
9540 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
9541 /// converted to a `BufferCollection` via
9542 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
9543 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
9544 /// the sync step and can create multiple tokens at once.
9545 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
9546 let _response = self.client.send_query::<
9547 fidl::encoding::EmptyPayload,
9548 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
9549 BufferCollectionTokenGroupMarker,
9550 >(
9551 (),
9552 0x11ac2555cf575b54,
9553 fidl::encoding::DynamicFlags::FLEXIBLE,
9554 ___deadline,
9555 )?
9556 .into_result::<BufferCollectionTokenGroupMarker>("sync")?;
9557 Ok(_response)
9558 }
9559
9560 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
9561 ///
9562 /// Normally a participant will convert a `BufferCollectionToken` into a
9563 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
9564 /// `Release` via the token (and then close the channel immediately or
9565 /// shortly later in response to server closing the server end), which
9566 /// avoids causing buffer collection failure. Without a prior `Release`,
9567 /// closing the `BufferCollectionToken` client end will cause buffer
9568 /// collection failure.
9569 ///
9570 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
9571 ///
9572 /// By default the server handles unexpected closure of a
9573 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
9574 /// first) by failing the buffer collection. Partly this is to expedite
9575 /// closing VMO handles to reclaim memory when any participant fails. If a
9576 /// participant would like to cleanly close a `BufferCollection` without
9577 /// causing buffer collection failure, the participant can send `Release`
9578 /// before closing the `BufferCollection` client end. The `Release` can
9579 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
9580 /// buffer collection won't require constraints from this node in order to
9581 /// allocate. If after `SetConstraints`, the constraints are retained and
9582 /// aggregated, despite the lack of `BufferCollection` connection at the
9583 /// time of constraints aggregation.
9584 ///
9585 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
9586 ///
9587 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
9588 /// end (without `Release` first) will trigger failure of the buffer
9589 /// collection. To close a `BufferCollectionTokenGroup` channel without
9590 /// failing the buffer collection, ensure that AllChildrenPresent() has been
9591 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
9592 /// client end.
9593 ///
9594 /// If `Release` occurs before
9595 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
9596 /// buffer collection will fail (triggered by reception of `Release` without
9597 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
9598 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
9599 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
9600 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
9601 /// close requires `AllChildrenPresent` (if not already sent), then
9602 /// `Release`, then close client end.
9603 ///
9604 /// If `Release` occurs after `AllChildrenPresent`, the children and all
9605 /// their constraints remain intact (just as they would if the
9606 /// `BufferCollectionTokenGroup` channel had remained open), and the client
9607 /// end close doesn't trigger buffer collection failure.
9608 ///
9609 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
9610 ///
9611 /// For brevity, the per-channel-protocol paragraphs above ignore the
9612 /// separate failure domain created by
9613 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
9614 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
9615 /// unexpectedly closes (without `Release` first) and that client end is
9616 /// under a failure domain, instead of failing the whole buffer collection,
9617 /// the failure domain is failed, but the buffer collection itself is
9618 /// isolated from failure of the failure domain. Such failure domains can be
9619 /// nested, in which case only the inner-most failure domain in which the
9620 /// `Node` resides fails.
9621 pub fn r#release(&self) -> Result<(), fidl::Error> {
9622 self.client.send::<fidl::encoding::EmptyPayload>(
9623 (),
9624 0x6a5cae7d6d6e04c6,
9625 fidl::encoding::DynamicFlags::FLEXIBLE,
9626 )
9627 }
9628
9629 /// Set a name for VMOs in this buffer collection.
9630 ///
9631 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
9632 /// will be truncated to fit. The name of the vmo will be suffixed with the
9633 /// buffer index within the collection (if the suffix fits within
9634 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
9635 /// listed in the inspect data.
9636 ///
9637 /// The name only affects VMOs allocated after the name is set; this call
9638 /// does not rename existing VMOs. If multiple clients set different names
9639 /// then the larger priority value will win. Setting a new name with the
9640 /// same priority as a prior name doesn't change the name.
9641 ///
9642 /// All table fields are currently required.
9643 ///
9644 /// + request `priority` The name is only set if this is the first `SetName`
9645 /// or if `priority` is greater than any previous `priority` value in
9646 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
9647 /// + request `name` The name for VMOs created under this buffer collection.
9648 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
9649 self.client.send::<NodeSetNameRequest>(
9650 payload,
9651 0xb41f1624f48c1e9,
9652 fidl::encoding::DynamicFlags::FLEXIBLE,
9653 )
9654 }
9655
9656 /// Set information about the current client that can be used by sysmem to
9657 /// help diagnose leaking memory and allocation stalls waiting for a
9658 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
9659 ///
9660 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
9661 /// `Node`(s) derived from this `Node`, unless overriden by
9662 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
9663 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
9664 ///
9665 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
9666 /// `Allocator` is the most efficient way to ensure that all
9667 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
9668 /// set, and is also more efficient than separately sending the same debug
9669 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
9670 /// created [`fuchsia.sysmem2/Node`].
9671 ///
9672 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
9673 /// indicate which client is closing their channel first, leading to subtree
9674 /// failure (which can be normal if the purpose of the subtree is over, but
9675 /// if happening earlier than expected, the client-channel-specific name can
9676 /// help diagnose where the failure is first coming from, from sysmem's
9677 /// point of view).
9678 ///
9679 /// All table fields are currently required.
9680 ///
9681 /// + request `name` This can be an arbitrary string, but the current
9682 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
9683 /// + request `id` This can be an arbitrary id, but the current process ID
9684 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
9685 pub fn r#set_debug_client_info(
9686 &self,
9687 mut payload: &NodeSetDebugClientInfoRequest,
9688 ) -> Result<(), fidl::Error> {
9689 self.client.send::<NodeSetDebugClientInfoRequest>(
9690 payload,
9691 0x5cde8914608d99b1,
9692 fidl::encoding::DynamicFlags::FLEXIBLE,
9693 )
9694 }
9695
9696 /// Sysmem logs a warning if sysmem hasn't seen
9697 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
9698 /// within 5 seconds after creation of a new collection.
9699 ///
9700 /// Clients can call this method to change when the log is printed. If
9701 /// multiple client set the deadline, it's unspecified which deadline will
9702 /// take effect.
9703 ///
9704 /// In most cases the default works well.
9705 ///
9706 /// All table fields are currently required.
9707 ///
9708 /// + request `deadline` The time at which sysmem will start trying to log
9709 /// the warning, unless all constraints are with sysmem by then.
9710 pub fn r#set_debug_timeout_log_deadline(
9711 &self,
9712 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
9713 ) -> Result<(), fidl::Error> {
9714 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
9715 payload,
9716 0x716b0af13d5c0806,
9717 fidl::encoding::DynamicFlags::FLEXIBLE,
9718 )
9719 }
9720
9721 /// This enables verbose logging for the buffer collection.
9722 ///
9723 /// Verbose logging includes constraints set via
9724 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
9725 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
9726 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
9727 /// the tree of `Node`(s).
9728 ///
9729 /// Normally sysmem prints only a single line complaint when aggregation
9730 /// fails, with just the specific detailed reason that aggregation failed,
9731 /// with little surrounding context. While this is often enough to diagnose
9732 /// a problem if only a small change was made and everything was working
9733 /// before the small change, it's often not particularly helpful for getting
9734 /// a new buffer collection to work for the first time. Especially with
9735 /// more complex trees of nodes, involving things like
9736 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
9737 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
9738 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
9739 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
9740 /// looks like and why it's failing a logical allocation, or why a tree or
9741 /// subtree is failing sooner than expected.
9742 ///
9743 /// The intent of the extra logging is to be acceptable from a performance
9744 /// point of view, under the assumption that verbose logging is only enabled
9745 /// on a low number of buffer collections. If we're not tracking down a bug,
9746 /// we shouldn't send this message.
9747 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
9748 self.client.send::<fidl::encoding::EmptyPayload>(
9749 (),
9750 0x5209c77415b4dfad,
9751 fidl::encoding::DynamicFlags::FLEXIBLE,
9752 )
9753 }
9754
9755 /// This gets a handle that can be used as a parameter to
9756 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
9757 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
9758 /// client obtained this handle from this `Node`.
9759 ///
9760 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
9761 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
9762 /// despite the two calls typically being on different channels.
9763 ///
9764 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
9765 ///
9766 /// All table fields are currently required.
9767 ///
9768 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
9769 /// different `Node` channel, to prove that the client obtained the handle
9770 /// from this `Node`.
9771 pub fn r#get_node_ref(
9772 &self,
9773 ___deadline: zx::MonotonicInstant,
9774 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
9775 let _response = self.client.send_query::<
9776 fidl::encoding::EmptyPayload,
9777 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
9778 BufferCollectionTokenGroupMarker,
9779 >(
9780 (),
9781 0x5b3d0e51614df053,
9782 fidl::encoding::DynamicFlags::FLEXIBLE,
9783 ___deadline,
9784 )?
9785 .into_result::<BufferCollectionTokenGroupMarker>("get_node_ref")?;
9786 Ok(_response)
9787 }
9788
9789 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
9790 /// rooted at a different child token of a common parent
9791 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
9792 /// passed-in `node_ref`.
9793 ///
9794 /// This call is for assisting with admission control de-duplication, and
9795 /// with debugging.
9796 ///
9797 /// The `node_ref` must be obtained using
9798 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
9799 ///
9800 /// The `node_ref` can be a duplicated handle; it's not necessary to call
9801 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
9802 ///
9803 /// If a calling token may not actually be a valid token at all due to a
9804 /// potentially hostile/untrusted provider of the token, call
9805 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
9806 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
9807 /// never responds due to a calling token not being a real token (not really
9808 /// talking to sysmem). Another option is to call
9809 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
9810 /// which also validates the token along with converting it to a
9811 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
9812 ///
9813 /// All table fields are currently required.
9814 ///
9815 /// - response `is_alternate`
9816 /// - true: The first parent node in common between the calling node and
9817 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
9818 /// that the calling `Node` and the `node_ref` `Node` will not have both
9819 /// their constraints apply - rather sysmem will choose one or the other
9820 /// of the constraints - never both. This is because only one child of
9821 /// a `BufferCollectionTokenGroup` is selected during logical
9822 /// allocation, with only that one child's subtree contributing to
9823 /// constraints aggregation.
9824 /// - false: The first parent node in common between the calling `Node`
9825 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
9826 /// Currently, this means the first parent node in common is a
9827 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
9828 /// `Release`ed). This means that the calling `Node` and the `node_ref`
9829 /// `Node` may have both their constraints apply during constraints
9830 /// aggregation of the logical allocation, if both `Node`(s) are
9831 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
9832 /// this case, there is no `BufferCollectionTokenGroup` that will
9833 /// directly prevent the two `Node`(s) from both being selected and
9834 /// their constraints both aggregated, but even when false, one or both
9835 /// `Node`(s) may still be eliminated from consideration if one or both
9836 /// `Node`(s) has a direct or indirect parent
9837 /// `BufferCollectionTokenGroup` which selects a child subtree other
9838 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
9839 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
9840 /// associated with the same buffer collection as the calling `Node`.
9841 /// Another reason for this error is if the `node_ref` is an
9842 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
9843 /// a real `node_ref` obtained from `GetNodeRef`.
9844 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
9845 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
9846 /// the needed rights expected on a real `node_ref`.
9847 /// * No other failing status codes are returned by this call. However,
9848 /// sysmem may add additional codes in future, so the client should have
9849 /// sensible default handling for any failing status code.
9850 pub fn r#is_alternate_for(
9851 &self,
9852 mut payload: NodeIsAlternateForRequest,
9853 ___deadline: zx::MonotonicInstant,
9854 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
9855 let _response = self.client.send_query::<
9856 NodeIsAlternateForRequest,
9857 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
9858 BufferCollectionTokenGroupMarker,
9859 >(
9860 &mut payload,
9861 0x3a58e00157e0825,
9862 fidl::encoding::DynamicFlags::FLEXIBLE,
9863 ___deadline,
9864 )?
9865 .into_result::<BufferCollectionTokenGroupMarker>("is_alternate_for")?;
9866 Ok(_response.map(|x| x))
9867 }
9868
9869 /// Get the buffer collection ID. This ID is also available from
9870 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
9871 /// within the collection).
9872 ///
9873 /// This call is mainly useful in situations where we can't convey a
9874 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
9875 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
9876 /// handle, which can be joined back up with a `BufferCollection` client end
9877 /// that was created via a different path. Prefer to convey a
9878 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
9879 ///
9880 /// Trusting a `buffer_collection_id` value from a source other than sysmem
9881 /// is analogous to trusting a koid value from a source other than zircon.
9882 /// Both should be avoided unless really necessary, and both require
9883 /// caution. In some situations it may be reasonable to refer to a
9884 /// pre-established `BufferCollection` by `buffer_collection_id` via a
9885 /// protocol for efficiency reasons, but an incoming value purporting to be
9886 /// a `buffer_collection_id` is not sufficient alone to justify granting the
9887 /// sender of the `buffer_collection_id` any capability. The sender must
9888 /// first prove to a receiver that the sender has/had a VMO or has/had a
9889 /// `BufferCollectionToken` to the same collection by sending a handle that
9890 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
9891 /// `buffer_collection_id` value. The receiver should take care to avoid
9892 /// assuming that a sender had a `BufferCollectionToken` in cases where the
9893 /// sender has only proven that the sender had a VMO.
9894 ///
9895 /// - response `buffer_collection_id` This ID is unique per buffer
9896 /// collection per boot. Each buffer is uniquely identified by the
9897 /// `buffer_collection_id` and `buffer_index` together.
9898 pub fn r#get_buffer_collection_id(
9899 &self,
9900 ___deadline: zx::MonotonicInstant,
9901 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
9902 let _response = self.client.send_query::<
9903 fidl::encoding::EmptyPayload,
9904 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
9905 BufferCollectionTokenGroupMarker,
9906 >(
9907 (),
9908 0x77d19a494b78ba8c,
9909 fidl::encoding::DynamicFlags::FLEXIBLE,
9910 ___deadline,
9911 )?
9912 .into_result::<BufferCollectionTokenGroupMarker>("get_buffer_collection_id")?;
9913 Ok(_response)
9914 }
9915
9916 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
9917 /// created after this message to weak, which means that a client's `Node`
9918 /// client end (or a child created after this message) is not alone
9919 /// sufficient to keep allocated VMOs alive.
9920 ///
9921 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
9922 /// `close_weak_asap`.
9923 ///
9924 /// This message is only permitted before the `Node` becomes ready for
9925 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
9926 /// * `BufferCollectionToken`: any time
9927 /// * `BufferCollection`: before `SetConstraints`
9928 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
9929 ///
9930 /// Currently, no conversion from strong `Node` to weak `Node` after ready
9931 /// for allocation is provided, but a client can simulate that by creating
9932 /// an additional `Node` before allocation and setting that additional
9933 /// `Node` to weak, and then potentially at some point later sending
9934 /// `Release` and closing the client end of the client's strong `Node`, but
9935 /// keeping the client's weak `Node`.
9936 ///
9937 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
9938 /// collection failure (all `Node` client end(s) will see
9939 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
9940 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
9941 /// this situation until all `Node`(s) are ready for allocation. For initial
9942 /// allocation to succeed, at least one strong `Node` is required to exist
9943 /// at allocation time, but after that client receives VMO handles, that
9944 /// client can `BufferCollection.Release` and close the client end without
9945 /// causing this type of failure.
9946 ///
9947 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
9948 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
9949 /// separately as appropriate.
9950 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
9951 self.client.send::<fidl::encoding::EmptyPayload>(
9952 (),
9953 0x22dd3ea514eeffe1,
9954 fidl::encoding::DynamicFlags::FLEXIBLE,
9955 )
9956 }
9957
9958 /// This indicates to sysmem that the client is prepared to pay attention to
9959 /// `close_weak_asap`.
9960 ///
9961 /// If sent, this message must be before
9962 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
9963 ///
9964 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
9965 /// send this message before `WaitForAllBuffersAllocated`, or a parent
9966 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
9967 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
9968 /// trigger buffer collection failure.
9969 ///
9970 /// This message is necessary because weak sysmem VMOs have not always been
9971 /// a thing, so older clients are not aware of the need to pay attention to
9972 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
9973 /// sysmem weak VMO handles asap. By having this message and requiring
9974 /// participants to indicate their acceptance of this aspect of the overall
9975 /// protocol, we avoid situations where an older client is delivered a weak
9976 /// VMO without any way for sysmem to get that VMO to close quickly later
9977 /// (and on a per-buffer basis).
9978 ///
9979 /// A participant that doesn't handle `close_weak_asap` and also doesn't
9980 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
9981 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
9982 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
9983 /// same participant has a child/delegate which does retrieve VMOs, that
9984 /// child/delegate will need to send `SetWeakOk` before
9985 /// `WaitForAllBuffersAllocated`.
9986 ///
9987 /// + request `for_child_nodes_also` If present and true, this means direct
9988 /// child nodes of this node created after this message plus all
9989 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
9990 /// those nodes. Any child node of this node that was created before this
9991 /// message is not included. This setting is "sticky" in the sense that a
9992 /// subsequent `SetWeakOk` without this bool set to true does not reset
9993 /// the server-side bool. If this creates a problem for a participant, a
9994 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
9995 /// tokens instead, as appropriate. A participant should only set
9996 /// `for_child_nodes_also` true if the participant can really promise to
9997 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
9998 /// weak VMO handles held by participants holding the corresponding child
9999 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
10000 /// which are using sysmem(1) can be weak, despite the clients of those
10001 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
10002 /// direct way to find out about `close_weak_asap`. This only applies to
10003 /// descendents of this `Node` which are using sysmem(1), not to this
10004 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
10005 /// token, which will fail allocation unless an ancestor of this `Node`
10006 /// specified `for_child_nodes_also` true.
10007 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
10008 self.client.send::<NodeSetWeakOkRequest>(
10009 &mut payload,
10010 0x38a44fc4d7724be9,
10011 fidl::encoding::DynamicFlags::FLEXIBLE,
10012 )
10013 }
10014
10015 /// The server_end will be closed after this `Node` and any child nodes have
10016 /// have released their buffer counts, making those counts available for
10017 /// reservation by a different `Node` via
10018 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
10019 ///
10020 /// The `Node` buffer counts may not be released until the entire tree of
10021 /// `Node`(s) is closed or failed, because
10022 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
10023 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
10024 /// `Node` buffer counts remain reserved until the orphaned node is later
10025 /// cleaned up.
10026 ///
10027 /// If the `Node` exceeds a fairly large number of attached eventpair server
10028 /// ends, a log message will indicate this and the `Node` (and the
10029 /// appropriate) sub-tree will fail.
10030 ///
10031 /// The `server_end` will remain open when
10032 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
10033 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
10034 /// [`fuchsia.sysmem2/BufferCollection`].
10035 ///
10036 /// This message can also be used with a
10037 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
10038 pub fn r#attach_node_tracking(
10039 &self,
10040 mut payload: NodeAttachNodeTrackingRequest,
10041 ) -> Result<(), fidl::Error> {
10042 self.client.send::<NodeAttachNodeTrackingRequest>(
10043 &mut payload,
10044 0x3f22f2a293d3cdac,
10045 fidl::encoding::DynamicFlags::FLEXIBLE,
10046 )
10047 }
10048
10049 /// Create a child [`fuchsia.sysmem2/BufferCollectionToken`]. Only one child
10050 /// (including its children) will be selected during allocation (or logical
10051 /// allocation).
10052 ///
10053 /// Before passing the client end of this token to
10054 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], completion of
10055 /// [`fuchsia.sysmem2/Node.Sync`] after
10056 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] is required.
10057 /// Or the client can use
10058 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`] which
10059 /// essentially includes the `Sync`.
10060 ///
10061 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
10062 /// fail the group's subtree and close the connection.
10063 ///
10064 /// After all children have been created, send AllChildrenPresent.
10065 ///
10066 /// + request `token_request` The server end of the new token channel.
10067 /// + request `rights_attenuation_mask` If ZX_RIGHT_SAME_RIGHTS, the created
10068 /// token allows the holder to get the same rights to buffers as the
10069 /// parent token (of the group) had. When the value isn't
10070 /// ZX_RIGHT_SAME_RIGHTS, the value is interpretted as a bitmask with 0
10071 /// bits ensuring those rights are attentuated, so 0xFFFFFFFF is a synonym
10072 /// for ZX_RIGHT_SAME_RIGHTS. The value 0 is not allowed and intentionally
10073 /// causes subtree failure.
10074 pub fn r#create_child(
10075 &self,
10076 mut payload: BufferCollectionTokenGroupCreateChildRequest,
10077 ) -> Result<(), fidl::Error> {
10078 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
10079 &mut payload,
10080 0x41a0075d419f30c5,
10081 fidl::encoding::DynamicFlags::FLEXIBLE,
10082 )
10083 }
10084
10085 /// Create 1 or more child tokens at once, synchronously. In contrast to
10086 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`], no
10087 /// [`fuchsia.sysmem2/Node.Sync`] is required before passing the client end
10088 /// of a returned token to
10089 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`].
10090 ///
10091 /// The lower-index child tokens are higher priority (attempted sooner) than
10092 /// higher-index child tokens.
10093 ///
10094 /// As per all child tokens, successful aggregation will choose exactly one
10095 /// child among all created children (across all children created across
10096 /// potentially multiple calls to
10097 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] and
10098 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`]).
10099 ///
10100 /// The maximum permissible total number of children per group, and total
10101 /// number of nodes in an overall tree (from the root) are capped to limits
10102 /// which are not configurable via these protocols.
10103 ///
10104 /// Sending CreateChildrenSync after AllChildrenPresent is not permitted;
10105 /// this will fail the group's subtree and close the connection.
10106 ///
10107 /// After all children have been created, send AllChildrenPresent.
10108 ///
10109 /// + request `rights_attentuation_masks` The size of the
10110 /// `rights_attentuation_masks` determines the number of created child
10111 /// tokens. The value ZX_RIGHT_SAME_RIGHTS doesn't attenuate any rights.
10112 /// The value 0xFFFFFFFF is a synonym for ZX_RIGHT_SAME_RIGHTS. For any
10113 /// other value, each 0 bit in the mask attenuates that right.
10114 /// - response `tokens` The created child tokens.
10115 pub fn r#create_children_sync(
10116 &self,
10117 mut payload: &BufferCollectionTokenGroupCreateChildrenSyncRequest,
10118 ___deadline: zx::MonotonicInstant,
10119 ) -> Result<BufferCollectionTokenGroupCreateChildrenSyncResponse, fidl::Error> {
10120 let _response = self.client.send_query::<
10121 BufferCollectionTokenGroupCreateChildrenSyncRequest,
10122 fidl::encoding::FlexibleType<BufferCollectionTokenGroupCreateChildrenSyncResponse>,
10123 BufferCollectionTokenGroupMarker,
10124 >(
10125 payload,
10126 0x15dea448c536070a,
10127 fidl::encoding::DynamicFlags::FLEXIBLE,
10128 ___deadline,
10129 )?
10130 .into_result::<BufferCollectionTokenGroupMarker>("create_children_sync")?;
10131 Ok(_response)
10132 }
10133
10134 /// Indicate that no more children will be created.
10135 ///
10136 /// After creating all children, the client should send
10137 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent`] to
10138 /// inform sysmem that no more children will be created, so that sysmem can
10139 /// know when it's ok to start aggregating constraints.
10140 ///
10141 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
10142 /// fail the group's subtree and close the connection.
10143 ///
10144 /// If [`fuchsia.sysmem2/Node.Release`] is to be sent, it should be sent
10145 /// after `AllChildrenPresent`, else failure of the group's subtree will be
10146 /// triggered. This is intentionally not analogous to how `Release` without
10147 /// prior [`fuchsia.sysmem2/BufferCollection.SetConstraints`] doesn't cause
10148 /// subtree failure.
10149 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
10150 self.client.send::<fidl::encoding::EmptyPayload>(
10151 (),
10152 0x5c327e4a23391312,
10153 fidl::encoding::DynamicFlags::FLEXIBLE,
10154 )
10155 }
10156}
10157
10158#[cfg(target_os = "fuchsia")]
10159impl From<BufferCollectionTokenGroupSynchronousProxy> for zx::NullableHandle {
10160 fn from(value: BufferCollectionTokenGroupSynchronousProxy) -> Self {
10161 value.into_channel().into()
10162 }
10163}
10164
10165#[cfg(target_os = "fuchsia")]
10166impl From<fidl::Channel> for BufferCollectionTokenGroupSynchronousProxy {
10167 fn from(value: fidl::Channel) -> Self {
10168 Self::new(value)
10169 }
10170}
10171
10172#[cfg(target_os = "fuchsia")]
10173impl fidl::endpoints::FromClient for BufferCollectionTokenGroupSynchronousProxy {
10174 type Protocol = BufferCollectionTokenGroupMarker;
10175
10176 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionTokenGroupMarker>) -> Self {
10177 Self::new(value.into_channel())
10178 }
10179}
10180
10181#[derive(Debug, Clone)]
10182pub struct BufferCollectionTokenGroupProxy {
10183 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
10184}
10185
10186impl fidl::endpoints::Proxy for BufferCollectionTokenGroupProxy {
10187 type Protocol = BufferCollectionTokenGroupMarker;
10188
10189 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
10190 Self::new(inner)
10191 }
10192
10193 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
10194 self.client.into_channel().map_err(|client| Self { client })
10195 }
10196
10197 fn as_channel(&self) -> &::fidl::AsyncChannel {
10198 self.client.as_channel()
10199 }
10200}
10201
10202impl BufferCollectionTokenGroupProxy {
10203 /// Create a new Proxy for fuchsia.sysmem2/BufferCollectionTokenGroup.
10204 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
10205 let protocol_name =
10206 <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
10207 Self { client: fidl::client::Client::new(channel, protocol_name) }
10208 }
10209
10210 /// Get a Stream of events from the remote end of the protocol.
10211 ///
10212 /// # Panics
10213 ///
10214 /// Panics if the event stream was already taken.
10215 pub fn take_event_stream(&self) -> BufferCollectionTokenGroupEventStream {
10216 BufferCollectionTokenGroupEventStream { event_receiver: self.client.take_event_receiver() }
10217 }
10218
10219 /// Ensure that previous messages have been received server side. This is
10220 /// particularly useful after previous messages that created new tokens,
10221 /// because a token must be known to the sysmem server before sending the
10222 /// token to another participant.
10223 ///
10224 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
10225 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
10226 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
10227 /// to mitigate the possibility of a hostile/fake
10228 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
10229 /// Another way is to pass the token to
10230 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
10231 /// the token as part of exchanging it for a
10232 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
10233 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
10234 /// of stalling.
10235 ///
10236 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
10237 /// and then starting and completing a `Sync`, it's then safe to send the
10238 /// `BufferCollectionToken` client ends to other participants knowing the
10239 /// server will recognize the tokens when they're sent by the other
10240 /// participants to sysmem in a
10241 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
10242 /// efficient way to create tokens while avoiding unnecessary round trips.
10243 ///
10244 /// Other options include waiting for each
10245 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
10246 /// individually (using separate call to `Sync` after each), or calling
10247 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
10248 /// converted to a `BufferCollection` via
10249 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
10250 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
10251 /// the sync step and can create multiple tokens at once.
10252 pub fn r#sync(
10253 &self,
10254 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
10255 BufferCollectionTokenGroupProxyInterface::r#sync(self)
10256 }
10257
10258 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
10259 ///
10260 /// Normally a participant will convert a `BufferCollectionToken` into a
10261 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
10262 /// `Release` via the token (and then close the channel immediately or
10263 /// shortly later in response to server closing the server end), which
10264 /// avoids causing buffer collection failure. Without a prior `Release`,
10265 /// closing the `BufferCollectionToken` client end will cause buffer
10266 /// collection failure.
10267 ///
10268 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
10269 ///
10270 /// By default the server handles unexpected closure of a
10271 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
10272 /// first) by failing the buffer collection. Partly this is to expedite
10273 /// closing VMO handles to reclaim memory when any participant fails. If a
10274 /// participant would like to cleanly close a `BufferCollection` without
10275 /// causing buffer collection failure, the participant can send `Release`
10276 /// before closing the `BufferCollection` client end. The `Release` can
10277 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
10278 /// buffer collection won't require constraints from this node in order to
10279 /// allocate. If after `SetConstraints`, the constraints are retained and
10280 /// aggregated, despite the lack of `BufferCollection` connection at the
10281 /// time of constraints aggregation.
10282 ///
10283 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
10284 ///
10285 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
10286 /// end (without `Release` first) will trigger failure of the buffer
10287 /// collection. To close a `BufferCollectionTokenGroup` channel without
10288 /// failing the buffer collection, ensure that AllChildrenPresent() has been
10289 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
10290 /// client end.
10291 ///
10292 /// If `Release` occurs before
10293 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
10294 /// buffer collection will fail (triggered by reception of `Release` without
10295 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
10296 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
10297 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
10298 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
10299 /// close requires `AllChildrenPresent` (if not already sent), then
10300 /// `Release`, then close client end.
10301 ///
10302 /// If `Release` occurs after `AllChildrenPresent`, the children and all
10303 /// their constraints remain intact (just as they would if the
10304 /// `BufferCollectionTokenGroup` channel had remained open), and the client
10305 /// end close doesn't trigger buffer collection failure.
10306 ///
10307 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
10308 ///
10309 /// For brevity, the per-channel-protocol paragraphs above ignore the
10310 /// separate failure domain created by
10311 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
10312 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
10313 /// unexpectedly closes (without `Release` first) and that client end is
10314 /// under a failure domain, instead of failing the whole buffer collection,
10315 /// the failure domain is failed, but the buffer collection itself is
10316 /// isolated from failure of the failure domain. Such failure domains can be
10317 /// nested, in which case only the inner-most failure domain in which the
10318 /// `Node` resides fails.
10319 pub fn r#release(&self) -> Result<(), fidl::Error> {
10320 BufferCollectionTokenGroupProxyInterface::r#release(self)
10321 }
10322
10323 /// Set a name for VMOs in this buffer collection.
10324 ///
10325 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
10326 /// will be truncated to fit. The name of the vmo will be suffixed with the
10327 /// buffer index within the collection (if the suffix fits within
10328 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
10329 /// listed in the inspect data.
10330 ///
10331 /// The name only affects VMOs allocated after the name is set; this call
10332 /// does not rename existing VMOs. If multiple clients set different names
10333 /// then the larger priority value will win. Setting a new name with the
10334 /// same priority as a prior name doesn't change the name.
10335 ///
10336 /// All table fields are currently required.
10337 ///
10338 /// + request `priority` The name is only set if this is the first `SetName`
10339 /// or if `priority` is greater than any previous `priority` value in
10340 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
10341 /// + request `name` The name for VMOs created under this buffer collection.
10342 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
10343 BufferCollectionTokenGroupProxyInterface::r#set_name(self, payload)
10344 }
10345
10346 /// Set information about the current client that can be used by sysmem to
10347 /// help diagnose leaking memory and allocation stalls waiting for a
10348 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
10349 ///
10350 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
10351 /// `Node`(s) derived from this `Node`, unless overriden by
10352 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
10353 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
10354 ///
10355 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
10356 /// `Allocator` is the most efficient way to ensure that all
10357 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
10358 /// set, and is also more efficient than separately sending the same debug
10359 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
10360 /// created [`fuchsia.sysmem2/Node`].
10361 ///
10362 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
10363 /// indicate which client is closing their channel first, leading to subtree
10364 /// failure (which can be normal if the purpose of the subtree is over, but
10365 /// if happening earlier than expected, the client-channel-specific name can
10366 /// help diagnose where the failure is first coming from, from sysmem's
10367 /// point of view).
10368 ///
10369 /// All table fields are currently required.
10370 ///
10371 /// + request `name` This can be an arbitrary string, but the current
10372 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
10373 /// + request `id` This can be an arbitrary id, but the current process ID
10374 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
10375 pub fn r#set_debug_client_info(
10376 &self,
10377 mut payload: &NodeSetDebugClientInfoRequest,
10378 ) -> Result<(), fidl::Error> {
10379 BufferCollectionTokenGroupProxyInterface::r#set_debug_client_info(self, payload)
10380 }
10381
10382 /// Sysmem logs a warning if sysmem hasn't seen
10383 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
10384 /// within 5 seconds after creation of a new collection.
10385 ///
10386 /// Clients can call this method to change when the log is printed. If
10387 /// multiple client set the deadline, it's unspecified which deadline will
10388 /// take effect.
10389 ///
10390 /// In most cases the default works well.
10391 ///
10392 /// All table fields are currently required.
10393 ///
10394 /// + request `deadline` The time at which sysmem will start trying to log
10395 /// the warning, unless all constraints are with sysmem by then.
10396 pub fn r#set_debug_timeout_log_deadline(
10397 &self,
10398 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
10399 ) -> Result<(), fidl::Error> {
10400 BufferCollectionTokenGroupProxyInterface::r#set_debug_timeout_log_deadline(self, payload)
10401 }
10402
10403 /// This enables verbose logging for the buffer collection.
10404 ///
10405 /// Verbose logging includes constraints set via
10406 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
10407 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
10408 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
10409 /// the tree of `Node`(s).
10410 ///
10411 /// Normally sysmem prints only a single line complaint when aggregation
10412 /// fails, with just the specific detailed reason that aggregation failed,
10413 /// with little surrounding context. While this is often enough to diagnose
10414 /// a problem if only a small change was made and everything was working
10415 /// before the small change, it's often not particularly helpful for getting
10416 /// a new buffer collection to work for the first time. Especially with
10417 /// more complex trees of nodes, involving things like
10418 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
10419 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
10420 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
10421 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
10422 /// looks like and why it's failing a logical allocation, or why a tree or
10423 /// subtree is failing sooner than expected.
10424 ///
10425 /// The intent of the extra logging is to be acceptable from a performance
10426 /// point of view, under the assumption that verbose logging is only enabled
10427 /// on a low number of buffer collections. If we're not tracking down a bug,
10428 /// we shouldn't send this message.
10429 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
10430 BufferCollectionTokenGroupProxyInterface::r#set_verbose_logging(self)
10431 }
10432
10433 /// This gets a handle that can be used as a parameter to
10434 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
10435 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
10436 /// client obtained this handle from this `Node`.
10437 ///
10438 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
10439 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
10440 /// despite the two calls typically being on different channels.
10441 ///
10442 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
10443 ///
10444 /// All table fields are currently required.
10445 ///
10446 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
10447 /// different `Node` channel, to prove that the client obtained the handle
10448 /// from this `Node`.
10449 pub fn r#get_node_ref(
10450 &self,
10451 ) -> fidl::client::QueryResponseFut<
10452 NodeGetNodeRefResponse,
10453 fidl::encoding::DefaultFuchsiaResourceDialect,
10454 > {
10455 BufferCollectionTokenGroupProxyInterface::r#get_node_ref(self)
10456 }
10457
10458 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
10459 /// rooted at a different child token of a common parent
10460 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
10461 /// passed-in `node_ref`.
10462 ///
10463 /// This call is for assisting with admission control de-duplication, and
10464 /// with debugging.
10465 ///
10466 /// The `node_ref` must be obtained using
10467 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
10468 ///
10469 /// The `node_ref` can be a duplicated handle; it's not necessary to call
10470 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
10471 ///
10472 /// If a calling token may not actually be a valid token at all due to a
10473 /// potentially hostile/untrusted provider of the token, call
10474 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
10475 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
10476 /// never responds due to a calling token not being a real token (not really
10477 /// talking to sysmem). Another option is to call
10478 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
10479 /// which also validates the token along with converting it to a
10480 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
10481 ///
10482 /// All table fields are currently required.
10483 ///
10484 /// - response `is_alternate`
10485 /// - true: The first parent node in common between the calling node and
10486 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
10487 /// that the calling `Node` and the `node_ref` `Node` will not have both
10488 /// their constraints apply - rather sysmem will choose one or the other
10489 /// of the constraints - never both. This is because only one child of
10490 /// a `BufferCollectionTokenGroup` is selected during logical
10491 /// allocation, with only that one child's subtree contributing to
10492 /// constraints aggregation.
10493 /// - false: The first parent node in common between the calling `Node`
10494 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
10495 /// Currently, this means the first parent node in common is a
10496 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
10497 /// `Release`ed). This means that the calling `Node` and the `node_ref`
10498 /// `Node` may have both their constraints apply during constraints
10499 /// aggregation of the logical allocation, if both `Node`(s) are
10500 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
10501 /// this case, there is no `BufferCollectionTokenGroup` that will
10502 /// directly prevent the two `Node`(s) from both being selected and
10503 /// their constraints both aggregated, but even when false, one or both
10504 /// `Node`(s) may still be eliminated from consideration if one or both
10505 /// `Node`(s) has a direct or indirect parent
10506 /// `BufferCollectionTokenGroup` which selects a child subtree other
10507 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
10508 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
10509 /// associated with the same buffer collection as the calling `Node`.
10510 /// Another reason for this error is if the `node_ref` is an
10511 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
10512 /// a real `node_ref` obtained from `GetNodeRef`.
10513 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
10514 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
10515 /// the needed rights expected on a real `node_ref`.
10516 /// * No other failing status codes are returned by this call. However,
10517 /// sysmem may add additional codes in future, so the client should have
10518 /// sensible default handling for any failing status code.
10519 pub fn r#is_alternate_for(
10520 &self,
10521 mut payload: NodeIsAlternateForRequest,
10522 ) -> fidl::client::QueryResponseFut<
10523 NodeIsAlternateForResult,
10524 fidl::encoding::DefaultFuchsiaResourceDialect,
10525 > {
10526 BufferCollectionTokenGroupProxyInterface::r#is_alternate_for(self, payload)
10527 }
10528
10529 /// Get the buffer collection ID. This ID is also available from
10530 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
10531 /// within the collection).
10532 ///
10533 /// This call is mainly useful in situations where we can't convey a
10534 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
10535 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
10536 /// handle, which can be joined back up with a `BufferCollection` client end
10537 /// that was created via a different path. Prefer to convey a
10538 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
10539 ///
10540 /// Trusting a `buffer_collection_id` value from a source other than sysmem
10541 /// is analogous to trusting a koid value from a source other than zircon.
10542 /// Both should be avoided unless really necessary, and both require
10543 /// caution. In some situations it may be reasonable to refer to a
10544 /// pre-established `BufferCollection` by `buffer_collection_id` via a
10545 /// protocol for efficiency reasons, but an incoming value purporting to be
10546 /// a `buffer_collection_id` is not sufficient alone to justify granting the
10547 /// sender of the `buffer_collection_id` any capability. The sender must
10548 /// first prove to a receiver that the sender has/had a VMO or has/had a
10549 /// `BufferCollectionToken` to the same collection by sending a handle that
10550 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
10551 /// `buffer_collection_id` value. The receiver should take care to avoid
10552 /// assuming that a sender had a `BufferCollectionToken` in cases where the
10553 /// sender has only proven that the sender had a VMO.
10554 ///
10555 /// - response `buffer_collection_id` This ID is unique per buffer
10556 /// collection per boot. Each buffer is uniquely identified by the
10557 /// `buffer_collection_id` and `buffer_index` together.
10558 pub fn r#get_buffer_collection_id(
10559 &self,
10560 ) -> fidl::client::QueryResponseFut<
10561 NodeGetBufferCollectionIdResponse,
10562 fidl::encoding::DefaultFuchsiaResourceDialect,
10563 > {
10564 BufferCollectionTokenGroupProxyInterface::r#get_buffer_collection_id(self)
10565 }
10566
10567 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
10568 /// created after this message to weak, which means that a client's `Node`
10569 /// client end (or a child created after this message) is not alone
10570 /// sufficient to keep allocated VMOs alive.
10571 ///
10572 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
10573 /// `close_weak_asap`.
10574 ///
10575 /// This message is only permitted before the `Node` becomes ready for
10576 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
10577 /// * `BufferCollectionToken`: any time
10578 /// * `BufferCollection`: before `SetConstraints`
10579 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
10580 ///
10581 /// Currently, no conversion from strong `Node` to weak `Node` after ready
10582 /// for allocation is provided, but a client can simulate that by creating
10583 /// an additional `Node` before allocation and setting that additional
10584 /// `Node` to weak, and then potentially at some point later sending
10585 /// `Release` and closing the client end of the client's strong `Node`, but
10586 /// keeping the client's weak `Node`.
10587 ///
10588 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
10589 /// collection failure (all `Node` client end(s) will see
10590 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
10591 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
10592 /// this situation until all `Node`(s) are ready for allocation. For initial
10593 /// allocation to succeed, at least one strong `Node` is required to exist
10594 /// at allocation time, but after that client receives VMO handles, that
10595 /// client can `BufferCollection.Release` and close the client end without
10596 /// causing this type of failure.
10597 ///
10598 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
10599 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
10600 /// separately as appropriate.
10601 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
10602 BufferCollectionTokenGroupProxyInterface::r#set_weak(self)
10603 }
10604
10605 /// This indicates to sysmem that the client is prepared to pay attention to
10606 /// `close_weak_asap`.
10607 ///
10608 /// If sent, this message must be before
10609 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
10610 ///
10611 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
10612 /// send this message before `WaitForAllBuffersAllocated`, or a parent
10613 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
10614 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
10615 /// trigger buffer collection failure.
10616 ///
10617 /// This message is necessary because weak sysmem VMOs have not always been
10618 /// a thing, so older clients are not aware of the need to pay attention to
10619 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
10620 /// sysmem weak VMO handles asap. By having this message and requiring
10621 /// participants to indicate their acceptance of this aspect of the overall
10622 /// protocol, we avoid situations where an older client is delivered a weak
10623 /// VMO without any way for sysmem to get that VMO to close quickly later
10624 /// (and on a per-buffer basis).
10625 ///
10626 /// A participant that doesn't handle `close_weak_asap` and also doesn't
10627 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
10628 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
10629 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
10630 /// same participant has a child/delegate which does retrieve VMOs, that
10631 /// child/delegate will need to send `SetWeakOk` before
10632 /// `WaitForAllBuffersAllocated`.
10633 ///
10634 /// + request `for_child_nodes_also` If present and true, this means direct
10635 /// child nodes of this node created after this message plus all
10636 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
10637 /// those nodes. Any child node of this node that was created before this
10638 /// message is not included. This setting is "sticky" in the sense that a
10639 /// subsequent `SetWeakOk` without this bool set to true does not reset
10640 /// the server-side bool. If this creates a problem for a participant, a
10641 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
10642 /// tokens instead, as appropriate. A participant should only set
10643 /// `for_child_nodes_also` true if the participant can really promise to
10644 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
10645 /// weak VMO handles held by participants holding the corresponding child
10646 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
10647 /// which are using sysmem(1) can be weak, despite the clients of those
10648 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
10649 /// direct way to find out about `close_weak_asap`. This only applies to
10650 /// descendents of this `Node` which are using sysmem(1), not to this
10651 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
10652 /// token, which will fail allocation unless an ancestor of this `Node`
10653 /// specified `for_child_nodes_also` true.
10654 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
10655 BufferCollectionTokenGroupProxyInterface::r#set_weak_ok(self, payload)
10656 }
10657
10658 /// The server_end will be closed after this `Node` and any child nodes have
10659 /// have released their buffer counts, making those counts available for
10660 /// reservation by a different `Node` via
10661 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
10662 ///
10663 /// The `Node` buffer counts may not be released until the entire tree of
10664 /// `Node`(s) is closed or failed, because
10665 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
10666 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
10667 /// `Node` buffer counts remain reserved until the orphaned node is later
10668 /// cleaned up.
10669 ///
10670 /// If the `Node` exceeds a fairly large number of attached eventpair server
10671 /// ends, a log message will indicate this and the `Node` (and the
10672 /// appropriate) sub-tree will fail.
10673 ///
10674 /// The `server_end` will remain open when
10675 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
10676 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
10677 /// [`fuchsia.sysmem2/BufferCollection`].
10678 ///
10679 /// This message can also be used with a
10680 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
10681 pub fn r#attach_node_tracking(
10682 &self,
10683 mut payload: NodeAttachNodeTrackingRequest,
10684 ) -> Result<(), fidl::Error> {
10685 BufferCollectionTokenGroupProxyInterface::r#attach_node_tracking(self, payload)
10686 }
10687
10688 /// Create a child [`fuchsia.sysmem2/BufferCollectionToken`]. Only one child
10689 /// (including its children) will be selected during allocation (or logical
10690 /// allocation).
10691 ///
10692 /// Before passing the client end of this token to
10693 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], completion of
10694 /// [`fuchsia.sysmem2/Node.Sync`] after
10695 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] is required.
10696 /// Or the client can use
10697 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`] which
10698 /// essentially includes the `Sync`.
10699 ///
10700 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
10701 /// fail the group's subtree and close the connection.
10702 ///
10703 /// After all children have been created, send AllChildrenPresent.
10704 ///
10705 /// + request `token_request` The server end of the new token channel.
10706 /// + request `rights_attenuation_mask` If ZX_RIGHT_SAME_RIGHTS, the created
10707 /// token allows the holder to get the same rights to buffers as the
10708 /// parent token (of the group) had. When the value isn't
10709 /// ZX_RIGHT_SAME_RIGHTS, the value is interpretted as a bitmask with 0
10710 /// bits ensuring those rights are attentuated, so 0xFFFFFFFF is a synonym
10711 /// for ZX_RIGHT_SAME_RIGHTS. The value 0 is not allowed and intentionally
10712 /// causes subtree failure.
10713 pub fn r#create_child(
10714 &self,
10715 mut payload: BufferCollectionTokenGroupCreateChildRequest,
10716 ) -> Result<(), fidl::Error> {
10717 BufferCollectionTokenGroupProxyInterface::r#create_child(self, payload)
10718 }
10719
10720 /// Create 1 or more child tokens at once, synchronously. In contrast to
10721 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`], no
10722 /// [`fuchsia.sysmem2/Node.Sync`] is required before passing the client end
10723 /// of a returned token to
10724 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`].
10725 ///
10726 /// The lower-index child tokens are higher priority (attempted sooner) than
10727 /// higher-index child tokens.
10728 ///
10729 /// As per all child tokens, successful aggregation will choose exactly one
10730 /// child among all created children (across all children created across
10731 /// potentially multiple calls to
10732 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] and
10733 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`]).
10734 ///
10735 /// The maximum permissible total number of children per group, and total
10736 /// number of nodes in an overall tree (from the root) are capped to limits
10737 /// which are not configurable via these protocols.
10738 ///
10739 /// Sending CreateChildrenSync after AllChildrenPresent is not permitted;
10740 /// this will fail the group's subtree and close the connection.
10741 ///
10742 /// After all children have been created, send AllChildrenPresent.
10743 ///
10744 /// + request `rights_attentuation_masks` The size of the
10745 /// `rights_attentuation_masks` determines the number of created child
10746 /// tokens. The value ZX_RIGHT_SAME_RIGHTS doesn't attenuate any rights.
10747 /// The value 0xFFFFFFFF is a synonym for ZX_RIGHT_SAME_RIGHTS. For any
10748 /// other value, each 0 bit in the mask attenuates that right.
10749 /// - response `tokens` The created child tokens.
10750 pub fn r#create_children_sync(
10751 &self,
10752 mut payload: &BufferCollectionTokenGroupCreateChildrenSyncRequest,
10753 ) -> fidl::client::QueryResponseFut<
10754 BufferCollectionTokenGroupCreateChildrenSyncResponse,
10755 fidl::encoding::DefaultFuchsiaResourceDialect,
10756 > {
10757 BufferCollectionTokenGroupProxyInterface::r#create_children_sync(self, payload)
10758 }
10759
10760 /// Indicate that no more children will be created.
10761 ///
10762 /// After creating all children, the client should send
10763 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent`] to
10764 /// inform sysmem that no more children will be created, so that sysmem can
10765 /// know when it's ok to start aggregating constraints.
10766 ///
10767 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
10768 /// fail the group's subtree and close the connection.
10769 ///
10770 /// If [`fuchsia.sysmem2/Node.Release`] is to be sent, it should be sent
10771 /// after `AllChildrenPresent`, else failure of the group's subtree will be
10772 /// triggered. This is intentionally not analogous to how `Release` without
10773 /// prior [`fuchsia.sysmem2/BufferCollection.SetConstraints`] doesn't cause
10774 /// subtree failure.
10775 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
10776 BufferCollectionTokenGroupProxyInterface::r#all_children_present(self)
10777 }
10778}
10779
10780impl BufferCollectionTokenGroupProxyInterface for BufferCollectionTokenGroupProxy {
10781 type SyncResponseFut =
10782 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
10783 fn r#sync(&self) -> Self::SyncResponseFut {
10784 fn _decode(
10785 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10786 ) -> Result<(), fidl::Error> {
10787 let _response = fidl::client::decode_transaction_body::<
10788 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
10789 fidl::encoding::DefaultFuchsiaResourceDialect,
10790 0x11ac2555cf575b54,
10791 >(_buf?)?
10792 .into_result::<BufferCollectionTokenGroupMarker>("sync")?;
10793 Ok(_response)
10794 }
10795 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
10796 (),
10797 0x11ac2555cf575b54,
10798 fidl::encoding::DynamicFlags::FLEXIBLE,
10799 _decode,
10800 )
10801 }
10802
10803 fn r#release(&self) -> Result<(), fidl::Error> {
10804 self.client.send::<fidl::encoding::EmptyPayload>(
10805 (),
10806 0x6a5cae7d6d6e04c6,
10807 fidl::encoding::DynamicFlags::FLEXIBLE,
10808 )
10809 }
10810
10811 fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
10812 self.client.send::<NodeSetNameRequest>(
10813 payload,
10814 0xb41f1624f48c1e9,
10815 fidl::encoding::DynamicFlags::FLEXIBLE,
10816 )
10817 }
10818
10819 fn r#set_debug_client_info(
10820 &self,
10821 mut payload: &NodeSetDebugClientInfoRequest,
10822 ) -> Result<(), fidl::Error> {
10823 self.client.send::<NodeSetDebugClientInfoRequest>(
10824 payload,
10825 0x5cde8914608d99b1,
10826 fidl::encoding::DynamicFlags::FLEXIBLE,
10827 )
10828 }
10829
10830 fn r#set_debug_timeout_log_deadline(
10831 &self,
10832 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
10833 ) -> Result<(), fidl::Error> {
10834 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
10835 payload,
10836 0x716b0af13d5c0806,
10837 fidl::encoding::DynamicFlags::FLEXIBLE,
10838 )
10839 }
10840
10841 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
10842 self.client.send::<fidl::encoding::EmptyPayload>(
10843 (),
10844 0x5209c77415b4dfad,
10845 fidl::encoding::DynamicFlags::FLEXIBLE,
10846 )
10847 }
10848
10849 type GetNodeRefResponseFut = fidl::client::QueryResponseFut<
10850 NodeGetNodeRefResponse,
10851 fidl::encoding::DefaultFuchsiaResourceDialect,
10852 >;
10853 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
10854 fn _decode(
10855 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10856 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
10857 let _response = fidl::client::decode_transaction_body::<
10858 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
10859 fidl::encoding::DefaultFuchsiaResourceDialect,
10860 0x5b3d0e51614df053,
10861 >(_buf?)?
10862 .into_result::<BufferCollectionTokenGroupMarker>("get_node_ref")?;
10863 Ok(_response)
10864 }
10865 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
10866 (),
10867 0x5b3d0e51614df053,
10868 fidl::encoding::DynamicFlags::FLEXIBLE,
10869 _decode,
10870 )
10871 }
10872
10873 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
10874 NodeIsAlternateForResult,
10875 fidl::encoding::DefaultFuchsiaResourceDialect,
10876 >;
10877 fn r#is_alternate_for(
10878 &self,
10879 mut payload: NodeIsAlternateForRequest,
10880 ) -> Self::IsAlternateForResponseFut {
10881 fn _decode(
10882 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10883 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
10884 let _response = fidl::client::decode_transaction_body::<
10885 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
10886 fidl::encoding::DefaultFuchsiaResourceDialect,
10887 0x3a58e00157e0825,
10888 >(_buf?)?
10889 .into_result::<BufferCollectionTokenGroupMarker>("is_alternate_for")?;
10890 Ok(_response.map(|x| x))
10891 }
10892 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
10893 &mut payload,
10894 0x3a58e00157e0825,
10895 fidl::encoding::DynamicFlags::FLEXIBLE,
10896 _decode,
10897 )
10898 }
10899
10900 type GetBufferCollectionIdResponseFut = fidl::client::QueryResponseFut<
10901 NodeGetBufferCollectionIdResponse,
10902 fidl::encoding::DefaultFuchsiaResourceDialect,
10903 >;
10904 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut {
10905 fn _decode(
10906 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10907 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
10908 let _response = fidl::client::decode_transaction_body::<
10909 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
10910 fidl::encoding::DefaultFuchsiaResourceDialect,
10911 0x77d19a494b78ba8c,
10912 >(_buf?)?
10913 .into_result::<BufferCollectionTokenGroupMarker>("get_buffer_collection_id")?;
10914 Ok(_response)
10915 }
10916 self.client.send_query_and_decode::<
10917 fidl::encoding::EmptyPayload,
10918 NodeGetBufferCollectionIdResponse,
10919 >(
10920 (),
10921 0x77d19a494b78ba8c,
10922 fidl::encoding::DynamicFlags::FLEXIBLE,
10923 _decode,
10924 )
10925 }
10926
10927 fn r#set_weak(&self) -> Result<(), fidl::Error> {
10928 self.client.send::<fidl::encoding::EmptyPayload>(
10929 (),
10930 0x22dd3ea514eeffe1,
10931 fidl::encoding::DynamicFlags::FLEXIBLE,
10932 )
10933 }
10934
10935 fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
10936 self.client.send::<NodeSetWeakOkRequest>(
10937 &mut payload,
10938 0x38a44fc4d7724be9,
10939 fidl::encoding::DynamicFlags::FLEXIBLE,
10940 )
10941 }
10942
10943 fn r#attach_node_tracking(
10944 &self,
10945 mut payload: NodeAttachNodeTrackingRequest,
10946 ) -> Result<(), fidl::Error> {
10947 self.client.send::<NodeAttachNodeTrackingRequest>(
10948 &mut payload,
10949 0x3f22f2a293d3cdac,
10950 fidl::encoding::DynamicFlags::FLEXIBLE,
10951 )
10952 }
10953
10954 fn r#create_child(
10955 &self,
10956 mut payload: BufferCollectionTokenGroupCreateChildRequest,
10957 ) -> Result<(), fidl::Error> {
10958 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
10959 &mut payload,
10960 0x41a0075d419f30c5,
10961 fidl::encoding::DynamicFlags::FLEXIBLE,
10962 )
10963 }
10964
10965 type CreateChildrenSyncResponseFut = fidl::client::QueryResponseFut<
10966 BufferCollectionTokenGroupCreateChildrenSyncResponse,
10967 fidl::encoding::DefaultFuchsiaResourceDialect,
10968 >;
10969 fn r#create_children_sync(
10970 &self,
10971 mut payload: &BufferCollectionTokenGroupCreateChildrenSyncRequest,
10972 ) -> Self::CreateChildrenSyncResponseFut {
10973 fn _decode(
10974 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10975 ) -> Result<BufferCollectionTokenGroupCreateChildrenSyncResponse, fidl::Error> {
10976 let _response = fidl::client::decode_transaction_body::<
10977 fidl::encoding::FlexibleType<BufferCollectionTokenGroupCreateChildrenSyncResponse>,
10978 fidl::encoding::DefaultFuchsiaResourceDialect,
10979 0x15dea448c536070a,
10980 >(_buf?)?
10981 .into_result::<BufferCollectionTokenGroupMarker>("create_children_sync")?;
10982 Ok(_response)
10983 }
10984 self.client.send_query_and_decode::<
10985 BufferCollectionTokenGroupCreateChildrenSyncRequest,
10986 BufferCollectionTokenGroupCreateChildrenSyncResponse,
10987 >(
10988 payload,
10989 0x15dea448c536070a,
10990 fidl::encoding::DynamicFlags::FLEXIBLE,
10991 _decode,
10992 )
10993 }
10994
10995 fn r#all_children_present(&self) -> Result<(), fidl::Error> {
10996 self.client.send::<fidl::encoding::EmptyPayload>(
10997 (),
10998 0x5c327e4a23391312,
10999 fidl::encoding::DynamicFlags::FLEXIBLE,
11000 )
11001 }
11002}
11003
11004pub struct BufferCollectionTokenGroupEventStream {
11005 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
11006}
11007
11008impl std::marker::Unpin for BufferCollectionTokenGroupEventStream {}
11009
11010impl futures::stream::FusedStream for BufferCollectionTokenGroupEventStream {
11011 fn is_terminated(&self) -> bool {
11012 self.event_receiver.is_terminated()
11013 }
11014}
11015
11016impl futures::Stream for BufferCollectionTokenGroupEventStream {
11017 type Item = Result<BufferCollectionTokenGroupEvent, fidl::Error>;
11018
11019 fn poll_next(
11020 mut self: std::pin::Pin<&mut Self>,
11021 cx: &mut std::task::Context<'_>,
11022 ) -> std::task::Poll<Option<Self::Item>> {
11023 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
11024 &mut self.event_receiver,
11025 cx
11026 )?) {
11027 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenGroupEvent::decode(buf))),
11028 None => std::task::Poll::Ready(None),
11029 }
11030 }
11031}
11032
11033#[derive(Debug)]
11034pub enum BufferCollectionTokenGroupEvent {
11035 #[non_exhaustive]
11036 _UnknownEvent {
11037 /// Ordinal of the event that was sent.
11038 ordinal: u64,
11039 },
11040}
11041
11042impl BufferCollectionTokenGroupEvent {
11043 /// Decodes a message buffer as a [`BufferCollectionTokenGroupEvent`].
11044 fn decode(
11045 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
11046 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
11047 let (bytes, _handles) = buf.split_mut();
11048 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
11049 debug_assert_eq!(tx_header.tx_id, 0);
11050 match tx_header.ordinal {
11051 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
11052 Ok(BufferCollectionTokenGroupEvent::_UnknownEvent {
11053 ordinal: tx_header.ordinal,
11054 })
11055 }
11056 _ => Err(fidl::Error::UnknownOrdinal {
11057 ordinal: tx_header.ordinal,
11058 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
11059 })
11060 }
11061 }
11062}
11063
11064/// A Stream of incoming requests for fuchsia.sysmem2/BufferCollectionTokenGroup.
11065pub struct BufferCollectionTokenGroupRequestStream {
11066 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11067 is_terminated: bool,
11068}
11069
11070impl std::marker::Unpin for BufferCollectionTokenGroupRequestStream {}
11071
11072impl futures::stream::FusedStream for BufferCollectionTokenGroupRequestStream {
11073 fn is_terminated(&self) -> bool {
11074 self.is_terminated
11075 }
11076}
11077
11078impl fidl::endpoints::RequestStream for BufferCollectionTokenGroupRequestStream {
11079 type Protocol = BufferCollectionTokenGroupMarker;
11080 type ControlHandle = BufferCollectionTokenGroupControlHandle;
11081
11082 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
11083 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
11084 }
11085
11086 fn control_handle(&self) -> Self::ControlHandle {
11087 BufferCollectionTokenGroupControlHandle { inner: self.inner.clone() }
11088 }
11089
11090 fn into_inner(
11091 self,
11092 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
11093 {
11094 (self.inner, self.is_terminated)
11095 }
11096
11097 fn from_inner(
11098 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11099 is_terminated: bool,
11100 ) -> Self {
11101 Self { inner, is_terminated }
11102 }
11103}
11104
11105impl futures::Stream for BufferCollectionTokenGroupRequestStream {
11106 type Item = Result<BufferCollectionTokenGroupRequest, fidl::Error>;
11107
11108 fn poll_next(
11109 mut self: std::pin::Pin<&mut Self>,
11110 cx: &mut std::task::Context<'_>,
11111 ) -> std::task::Poll<Option<Self::Item>> {
11112 let this = &mut *self;
11113 if this.inner.check_shutdown(cx) {
11114 this.is_terminated = true;
11115 return std::task::Poll::Ready(None);
11116 }
11117 if this.is_terminated {
11118 panic!("polled BufferCollectionTokenGroupRequestStream after completion");
11119 }
11120 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
11121 |bytes, handles| {
11122 match this.inner.channel().read_etc(cx, bytes, handles) {
11123 std::task::Poll::Ready(Ok(())) => {}
11124 std::task::Poll::Pending => return std::task::Poll::Pending,
11125 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
11126 this.is_terminated = true;
11127 return std::task::Poll::Ready(None);
11128 }
11129 std::task::Poll::Ready(Err(e)) => {
11130 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
11131 e.into(),
11132 ))));
11133 }
11134 }
11135
11136 // A message has been received from the channel
11137 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
11138
11139 std::task::Poll::Ready(Some(match header.ordinal {
11140 0x11ac2555cf575b54 => {
11141 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11142 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11143 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11144 let control_handle = BufferCollectionTokenGroupControlHandle {
11145 inner: this.inner.clone(),
11146 };
11147 Ok(BufferCollectionTokenGroupRequest::Sync {
11148 responder: BufferCollectionTokenGroupSyncResponder {
11149 control_handle: std::mem::ManuallyDrop::new(control_handle),
11150 tx_id: header.tx_id,
11151 },
11152 })
11153 }
11154 0x6a5cae7d6d6e04c6 => {
11155 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11156 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11157 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11158 let control_handle = BufferCollectionTokenGroupControlHandle {
11159 inner: this.inner.clone(),
11160 };
11161 Ok(BufferCollectionTokenGroupRequest::Release {
11162 control_handle,
11163 })
11164 }
11165 0xb41f1624f48c1e9 => {
11166 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11167 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11168 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
11169 let control_handle = BufferCollectionTokenGroupControlHandle {
11170 inner: this.inner.clone(),
11171 };
11172 Ok(BufferCollectionTokenGroupRequest::SetName {payload: req,
11173 control_handle,
11174 })
11175 }
11176 0x5cde8914608d99b1 => {
11177 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11178 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11179 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
11180 let control_handle = BufferCollectionTokenGroupControlHandle {
11181 inner: this.inner.clone(),
11182 };
11183 Ok(BufferCollectionTokenGroupRequest::SetDebugClientInfo {payload: req,
11184 control_handle,
11185 })
11186 }
11187 0x716b0af13d5c0806 => {
11188 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11189 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11190 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
11191 let control_handle = BufferCollectionTokenGroupControlHandle {
11192 inner: this.inner.clone(),
11193 };
11194 Ok(BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {payload: req,
11195 control_handle,
11196 })
11197 }
11198 0x5209c77415b4dfad => {
11199 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11200 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11201 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11202 let control_handle = BufferCollectionTokenGroupControlHandle {
11203 inner: this.inner.clone(),
11204 };
11205 Ok(BufferCollectionTokenGroupRequest::SetVerboseLogging {
11206 control_handle,
11207 })
11208 }
11209 0x5b3d0e51614df053 => {
11210 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11211 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11212 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11213 let control_handle = BufferCollectionTokenGroupControlHandle {
11214 inner: this.inner.clone(),
11215 };
11216 Ok(BufferCollectionTokenGroupRequest::GetNodeRef {
11217 responder: BufferCollectionTokenGroupGetNodeRefResponder {
11218 control_handle: std::mem::ManuallyDrop::new(control_handle),
11219 tx_id: header.tx_id,
11220 },
11221 })
11222 }
11223 0x3a58e00157e0825 => {
11224 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11225 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11226 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
11227 let control_handle = BufferCollectionTokenGroupControlHandle {
11228 inner: this.inner.clone(),
11229 };
11230 Ok(BufferCollectionTokenGroupRequest::IsAlternateFor {payload: req,
11231 responder: BufferCollectionTokenGroupIsAlternateForResponder {
11232 control_handle: std::mem::ManuallyDrop::new(control_handle),
11233 tx_id: header.tx_id,
11234 },
11235 })
11236 }
11237 0x77d19a494b78ba8c => {
11238 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11239 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11240 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11241 let control_handle = BufferCollectionTokenGroupControlHandle {
11242 inner: this.inner.clone(),
11243 };
11244 Ok(BufferCollectionTokenGroupRequest::GetBufferCollectionId {
11245 responder: BufferCollectionTokenGroupGetBufferCollectionIdResponder {
11246 control_handle: std::mem::ManuallyDrop::new(control_handle),
11247 tx_id: header.tx_id,
11248 },
11249 })
11250 }
11251 0x22dd3ea514eeffe1 => {
11252 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11253 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11254 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11255 let control_handle = BufferCollectionTokenGroupControlHandle {
11256 inner: this.inner.clone(),
11257 };
11258 Ok(BufferCollectionTokenGroupRequest::SetWeak {
11259 control_handle,
11260 })
11261 }
11262 0x38a44fc4d7724be9 => {
11263 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11264 let mut req = fidl::new_empty!(NodeSetWeakOkRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11265 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetWeakOkRequest>(&header, _body_bytes, handles, &mut req)?;
11266 let control_handle = BufferCollectionTokenGroupControlHandle {
11267 inner: this.inner.clone(),
11268 };
11269 Ok(BufferCollectionTokenGroupRequest::SetWeakOk {payload: req,
11270 control_handle,
11271 })
11272 }
11273 0x3f22f2a293d3cdac => {
11274 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11275 let mut req = fidl::new_empty!(NodeAttachNodeTrackingRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11276 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeAttachNodeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
11277 let control_handle = BufferCollectionTokenGroupControlHandle {
11278 inner: this.inner.clone(),
11279 };
11280 Ok(BufferCollectionTokenGroupRequest::AttachNodeTracking {payload: req,
11281 control_handle,
11282 })
11283 }
11284 0x41a0075d419f30c5 => {
11285 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11286 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11287 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildRequest>(&header, _body_bytes, handles, &mut req)?;
11288 let control_handle = BufferCollectionTokenGroupControlHandle {
11289 inner: this.inner.clone(),
11290 };
11291 Ok(BufferCollectionTokenGroupRequest::CreateChild {payload: req,
11292 control_handle,
11293 })
11294 }
11295 0x15dea448c536070a => {
11296 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11297 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildrenSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11298 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildrenSyncRequest>(&header, _body_bytes, handles, &mut req)?;
11299 let control_handle = BufferCollectionTokenGroupControlHandle {
11300 inner: this.inner.clone(),
11301 };
11302 Ok(BufferCollectionTokenGroupRequest::CreateChildrenSync {payload: req,
11303 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder {
11304 control_handle: std::mem::ManuallyDrop::new(control_handle),
11305 tx_id: header.tx_id,
11306 },
11307 })
11308 }
11309 0x5c327e4a23391312 => {
11310 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11311 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11312 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11313 let control_handle = BufferCollectionTokenGroupControlHandle {
11314 inner: this.inner.clone(),
11315 };
11316 Ok(BufferCollectionTokenGroupRequest::AllChildrenPresent {
11317 control_handle,
11318 })
11319 }
11320 _ if header.tx_id == 0 && header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
11321 Ok(BufferCollectionTokenGroupRequest::_UnknownMethod {
11322 ordinal: header.ordinal,
11323 control_handle: BufferCollectionTokenGroupControlHandle { inner: this.inner.clone() },
11324 method_type: fidl::MethodType::OneWay,
11325 })
11326 }
11327 _ if header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
11328 this.inner.send_framework_err(
11329 fidl::encoding::FrameworkErr::UnknownMethod,
11330 header.tx_id,
11331 header.ordinal,
11332 header.dynamic_flags(),
11333 (bytes, handles),
11334 )?;
11335 Ok(BufferCollectionTokenGroupRequest::_UnknownMethod {
11336 ordinal: header.ordinal,
11337 control_handle: BufferCollectionTokenGroupControlHandle { inner: this.inner.clone() },
11338 method_type: fidl::MethodType::TwoWay,
11339 })
11340 }
11341 _ => Err(fidl::Error::UnknownOrdinal {
11342 ordinal: header.ordinal,
11343 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
11344 }),
11345 }))
11346 },
11347 )
11348 }
11349}
11350
11351/// The sysmem implementation is consistent with a logical / conceptual model of
11352/// allocation / logical allocation as follows:
11353///
11354/// As usual, a logical allocation considers either the root and all nodes with
11355/// connectivity to the root that don't transit a [`fuchsia.sysmem2/Node`]
11356/// created with [`fuchsia.sysmem2/BufferCollection.AttachToken`], or a subtree
11357/// rooted at an `AttachToken` `Node` and all `Node`(s) with connectivity to
11358/// that subtree that don't transit another `AttachToken`. This is called the
11359/// logical allocation pruned subtree, or pruned subtree for short.
11360///
11361/// During constraints aggregation, each
11362/// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] will select a single child
11363/// `Node` among its direct children. The rest of the children will appear to
11364/// fail the logical allocation, while the selected child may succeed.
11365///
11366/// When more than one `BufferCollectionTokenGroup` exists in the overall
11367/// logical allocation pruned subtree, the relative priority between two groups
11368/// is equivalent to their ordering in a DFS pre-order iteration of the tree,
11369/// with parents higher priority than children, and left children higher
11370/// priority than right children.
11371///
11372/// When a particular child of a group is selected (whether provisionally during
11373/// a constraints aggregation attempt, or as a final selection), the
11374/// non-selection of other children of the group will "hide" any other groups
11375/// under those non-selected children.
11376///
11377/// Within a logical allocation, aggregation is attempted first by provisionally
11378/// selecting child 0 of the highest-priority group, and child 0 of the next
11379/// highest-priority group that isn't hidden by the provisional selections so
11380/// far, etc.
11381///
11382/// If that aggregation attempt fails, aggregation will be attempted with the
11383/// ordinal 0 child of all the same groups except the lowest priority non-hidden
11384/// group which will provisionally select its ordinal 1 child (and then child 2
11385/// and so on). If a new lowest-priority group is un-hidden as provisional
11386/// selections are updated, that newly un-hidden lowest-priority group has all
11387/// its children considered in order, before changing the provisional selection
11388/// in the former lowest-priority group. In terms of result, this is equivalent
11389/// to systematic enumeration of all possible combinations of choices in a
11390/// counting-like order updating the lowest-priority group the most often and
11391/// the highest-priority group the least often. Rather than actually attempting
11392/// aggregation with all the combinations, we can skip over combinations which
11393/// are redundant/equivalent due to hiding without any change to the result.
11394///
11395/// Attempted constraint aggregations of enumerated non-equivalent combinations
11396/// of choices continue in this manner until either (a) all aggregation attempts
11397/// fail in which case the overall logical allocation fails, or (b) until an
11398/// attempted aggregation succeeds, in which case buffer allocation (if needed;
11399/// if this is the pruned subtree rooted at the overall root `Node`) is
11400/// attempted once. If buffer allocation based on the first successful
11401/// constraints aggregation fails, the overall logical allocation fails (there
11402/// is no buffer allocation retry / re-attempt). If buffer allocation succeeds
11403/// (or is not needed due to being a pruned subtree that doesn't include the
11404/// root), the logical allocation succeeds.
11405///
11406/// If this prioritization scheme cannot reasonably work for your usage of
11407/// sysmem, please don't hesitate to contact sysmem folks to discuss potentially
11408/// adding a way to achieve what you need.
11409///
11410/// Please avoid creating a large number of `BufferCollectionTokenGroup`(s) per
11411/// logical allocation, especially with large number of children overall, and
11412/// especially in cases where aggregation may reasonably be expected to often
11413/// fail using ordinal 0 children and possibly with later children as well.
11414/// Sysmem mitigates potentially high time complexity of evaluating too many
11415/// child combinations/selections across too many groups by simply failing
11416/// logical allocation beyond a certain (fairly high, but not huge) max number
11417/// of considered group child combinations/selections. More advanced (and more
11418/// complicated) mitigation is not anticipated to be practically necessary or
11419/// worth the added complexity. Please contact sysmem folks if the max limit is
11420/// getting hit or if you anticipate it getting hit, to discuss potential
11421/// options.
11422///
11423/// Prefer to use multiple [`fuchsia.sysmem2/ImageFormatConstraints`] in a
11424/// single [`fuchsia.sysmem2/BufferCollectionConstraints`] when feasible (when a
11425/// participant just needs to express the ability to work with more than a
11426/// single [`fuchsia.images2/PixelFormat`], with sysmem choosing which
11427/// `PixelFormat` to use among those supported by all participants).
11428///
11429/// Similar to [`fuchsia.sysmem2/BufferCollectionToken`] and
11430/// [`fuchsia.sysmem2/BufferCollection`], closure of the
11431/// `BufferCollectionTokenGroup` channel without sending
11432/// [`fuchsia.sysmem2/Node.Release`] first will cause buffer collection failure
11433/// (or subtree failure if using
11434/// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
11435/// [`fuchsia.sysmem2/BufferCollection.AttachToken`] and the
11436/// `BufferCollectionTokenGroup` is part of a subtree under such a node that
11437/// doesn't propagate failure to its parent).
11438///
11439/// Epitaphs are not used in this protocol.
11440#[derive(Debug)]
11441pub enum BufferCollectionTokenGroupRequest {
11442 /// Ensure that previous messages have been received server side. This is
11443 /// particularly useful after previous messages that created new tokens,
11444 /// because a token must be known to the sysmem server before sending the
11445 /// token to another participant.
11446 ///
11447 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
11448 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
11449 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
11450 /// to mitigate the possibility of a hostile/fake
11451 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
11452 /// Another way is to pass the token to
11453 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
11454 /// the token as part of exchanging it for a
11455 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
11456 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
11457 /// of stalling.
11458 ///
11459 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
11460 /// and then starting and completing a `Sync`, it's then safe to send the
11461 /// `BufferCollectionToken` client ends to other participants knowing the
11462 /// server will recognize the tokens when they're sent by the other
11463 /// participants to sysmem in a
11464 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
11465 /// efficient way to create tokens while avoiding unnecessary round trips.
11466 ///
11467 /// Other options include waiting for each
11468 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
11469 /// individually (using separate call to `Sync` after each), or calling
11470 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
11471 /// converted to a `BufferCollection` via
11472 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
11473 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
11474 /// the sync step and can create multiple tokens at once.
11475 Sync { responder: BufferCollectionTokenGroupSyncResponder },
11476 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
11477 ///
11478 /// Normally a participant will convert a `BufferCollectionToken` into a
11479 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
11480 /// `Release` via the token (and then close the channel immediately or
11481 /// shortly later in response to server closing the server end), which
11482 /// avoids causing buffer collection failure. Without a prior `Release`,
11483 /// closing the `BufferCollectionToken` client end will cause buffer
11484 /// collection failure.
11485 ///
11486 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
11487 ///
11488 /// By default the server handles unexpected closure of a
11489 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
11490 /// first) by failing the buffer collection. Partly this is to expedite
11491 /// closing VMO handles to reclaim memory when any participant fails. If a
11492 /// participant would like to cleanly close a `BufferCollection` without
11493 /// causing buffer collection failure, the participant can send `Release`
11494 /// before closing the `BufferCollection` client end. The `Release` can
11495 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
11496 /// buffer collection won't require constraints from this node in order to
11497 /// allocate. If after `SetConstraints`, the constraints are retained and
11498 /// aggregated, despite the lack of `BufferCollection` connection at the
11499 /// time of constraints aggregation.
11500 ///
11501 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
11502 ///
11503 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
11504 /// end (without `Release` first) will trigger failure of the buffer
11505 /// collection. To close a `BufferCollectionTokenGroup` channel without
11506 /// failing the buffer collection, ensure that AllChildrenPresent() has been
11507 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
11508 /// client end.
11509 ///
11510 /// If `Release` occurs before
11511 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
11512 /// buffer collection will fail (triggered by reception of `Release` without
11513 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
11514 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
11515 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
11516 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
11517 /// close requires `AllChildrenPresent` (if not already sent), then
11518 /// `Release`, then close client end.
11519 ///
11520 /// If `Release` occurs after `AllChildrenPresent`, the children and all
11521 /// their constraints remain intact (just as they would if the
11522 /// `BufferCollectionTokenGroup` channel had remained open), and the client
11523 /// end close doesn't trigger buffer collection failure.
11524 ///
11525 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
11526 ///
11527 /// For brevity, the per-channel-protocol paragraphs above ignore the
11528 /// separate failure domain created by
11529 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
11530 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
11531 /// unexpectedly closes (without `Release` first) and that client end is
11532 /// under a failure domain, instead of failing the whole buffer collection,
11533 /// the failure domain is failed, but the buffer collection itself is
11534 /// isolated from failure of the failure domain. Such failure domains can be
11535 /// nested, in which case only the inner-most failure domain in which the
11536 /// `Node` resides fails.
11537 Release { control_handle: BufferCollectionTokenGroupControlHandle },
11538 /// Set a name for VMOs in this buffer collection.
11539 ///
11540 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
11541 /// will be truncated to fit. The name of the vmo will be suffixed with the
11542 /// buffer index within the collection (if the suffix fits within
11543 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
11544 /// listed in the inspect data.
11545 ///
11546 /// The name only affects VMOs allocated after the name is set; this call
11547 /// does not rename existing VMOs. If multiple clients set different names
11548 /// then the larger priority value will win. Setting a new name with the
11549 /// same priority as a prior name doesn't change the name.
11550 ///
11551 /// All table fields are currently required.
11552 ///
11553 /// + request `priority` The name is only set if this is the first `SetName`
11554 /// or if `priority` is greater than any previous `priority` value in
11555 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
11556 /// + request `name` The name for VMOs created under this buffer collection.
11557 SetName { payload: NodeSetNameRequest, control_handle: BufferCollectionTokenGroupControlHandle },
11558 /// Set information about the current client that can be used by sysmem to
11559 /// help diagnose leaking memory and allocation stalls waiting for a
11560 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
11561 ///
11562 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
11563 /// `Node`(s) derived from this `Node`, unless overriden by
11564 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
11565 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
11566 ///
11567 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
11568 /// `Allocator` is the most efficient way to ensure that all
11569 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
11570 /// set, and is also more efficient than separately sending the same debug
11571 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
11572 /// created [`fuchsia.sysmem2/Node`].
11573 ///
11574 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
11575 /// indicate which client is closing their channel first, leading to subtree
11576 /// failure (which can be normal if the purpose of the subtree is over, but
11577 /// if happening earlier than expected, the client-channel-specific name can
11578 /// help diagnose where the failure is first coming from, from sysmem's
11579 /// point of view).
11580 ///
11581 /// All table fields are currently required.
11582 ///
11583 /// + request `name` This can be an arbitrary string, but the current
11584 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
11585 /// + request `id` This can be an arbitrary id, but the current process ID
11586 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
11587 SetDebugClientInfo {
11588 payload: NodeSetDebugClientInfoRequest,
11589 control_handle: BufferCollectionTokenGroupControlHandle,
11590 },
11591 /// Sysmem logs a warning if sysmem hasn't seen
11592 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
11593 /// within 5 seconds after creation of a new collection.
11594 ///
11595 /// Clients can call this method to change when the log is printed. If
11596 /// multiple client set the deadline, it's unspecified which deadline will
11597 /// take effect.
11598 ///
11599 /// In most cases the default works well.
11600 ///
11601 /// All table fields are currently required.
11602 ///
11603 /// + request `deadline` The time at which sysmem will start trying to log
11604 /// the warning, unless all constraints are with sysmem by then.
11605 SetDebugTimeoutLogDeadline {
11606 payload: NodeSetDebugTimeoutLogDeadlineRequest,
11607 control_handle: BufferCollectionTokenGroupControlHandle,
11608 },
11609 /// This enables verbose logging for the buffer collection.
11610 ///
11611 /// Verbose logging includes constraints set via
11612 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
11613 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
11614 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
11615 /// the tree of `Node`(s).
11616 ///
11617 /// Normally sysmem prints only a single line complaint when aggregation
11618 /// fails, with just the specific detailed reason that aggregation failed,
11619 /// with little surrounding context. While this is often enough to diagnose
11620 /// a problem if only a small change was made and everything was working
11621 /// before the small change, it's often not particularly helpful for getting
11622 /// a new buffer collection to work for the first time. Especially with
11623 /// more complex trees of nodes, involving things like
11624 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
11625 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
11626 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
11627 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
11628 /// looks like and why it's failing a logical allocation, or why a tree or
11629 /// subtree is failing sooner than expected.
11630 ///
11631 /// The intent of the extra logging is to be acceptable from a performance
11632 /// point of view, under the assumption that verbose logging is only enabled
11633 /// on a low number of buffer collections. If we're not tracking down a bug,
11634 /// we shouldn't send this message.
11635 SetVerboseLogging { control_handle: BufferCollectionTokenGroupControlHandle },
11636 /// This gets a handle that can be used as a parameter to
11637 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
11638 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
11639 /// client obtained this handle from this `Node`.
11640 ///
11641 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
11642 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
11643 /// despite the two calls typically being on different channels.
11644 ///
11645 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
11646 ///
11647 /// All table fields are currently required.
11648 ///
11649 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
11650 /// different `Node` channel, to prove that the client obtained the handle
11651 /// from this `Node`.
11652 GetNodeRef { responder: BufferCollectionTokenGroupGetNodeRefResponder },
11653 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
11654 /// rooted at a different child token of a common parent
11655 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
11656 /// passed-in `node_ref`.
11657 ///
11658 /// This call is for assisting with admission control de-duplication, and
11659 /// with debugging.
11660 ///
11661 /// The `node_ref` must be obtained using
11662 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
11663 ///
11664 /// The `node_ref` can be a duplicated handle; it's not necessary to call
11665 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
11666 ///
11667 /// If a calling token may not actually be a valid token at all due to a
11668 /// potentially hostile/untrusted provider of the token, call
11669 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
11670 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
11671 /// never responds due to a calling token not being a real token (not really
11672 /// talking to sysmem). Another option is to call
11673 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
11674 /// which also validates the token along with converting it to a
11675 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
11676 ///
11677 /// All table fields are currently required.
11678 ///
11679 /// - response `is_alternate`
11680 /// - true: The first parent node in common between the calling node and
11681 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
11682 /// that the calling `Node` and the `node_ref` `Node` will not have both
11683 /// their constraints apply - rather sysmem will choose one or the other
11684 /// of the constraints - never both. This is because only one child of
11685 /// a `BufferCollectionTokenGroup` is selected during logical
11686 /// allocation, with only that one child's subtree contributing to
11687 /// constraints aggregation.
11688 /// - false: The first parent node in common between the calling `Node`
11689 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
11690 /// Currently, this means the first parent node in common is a
11691 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
11692 /// `Release`ed). This means that the calling `Node` and the `node_ref`
11693 /// `Node` may have both their constraints apply during constraints
11694 /// aggregation of the logical allocation, if both `Node`(s) are
11695 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
11696 /// this case, there is no `BufferCollectionTokenGroup` that will
11697 /// directly prevent the two `Node`(s) from both being selected and
11698 /// their constraints both aggregated, but even when false, one or both
11699 /// `Node`(s) may still be eliminated from consideration if one or both
11700 /// `Node`(s) has a direct or indirect parent
11701 /// `BufferCollectionTokenGroup` which selects a child subtree other
11702 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
11703 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
11704 /// associated with the same buffer collection as the calling `Node`.
11705 /// Another reason for this error is if the `node_ref` is an
11706 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
11707 /// a real `node_ref` obtained from `GetNodeRef`.
11708 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
11709 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
11710 /// the needed rights expected on a real `node_ref`.
11711 /// * No other failing status codes are returned by this call. However,
11712 /// sysmem may add additional codes in future, so the client should have
11713 /// sensible default handling for any failing status code.
11714 IsAlternateFor {
11715 payload: NodeIsAlternateForRequest,
11716 responder: BufferCollectionTokenGroupIsAlternateForResponder,
11717 },
11718 /// Get the buffer collection ID. This ID is also available from
11719 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
11720 /// within the collection).
11721 ///
11722 /// This call is mainly useful in situations where we can't convey a
11723 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
11724 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
11725 /// handle, which can be joined back up with a `BufferCollection` client end
11726 /// that was created via a different path. Prefer to convey a
11727 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
11728 ///
11729 /// Trusting a `buffer_collection_id` value from a source other than sysmem
11730 /// is analogous to trusting a koid value from a source other than zircon.
11731 /// Both should be avoided unless really necessary, and both require
11732 /// caution. In some situations it may be reasonable to refer to a
11733 /// pre-established `BufferCollection` by `buffer_collection_id` via a
11734 /// protocol for efficiency reasons, but an incoming value purporting to be
11735 /// a `buffer_collection_id` is not sufficient alone to justify granting the
11736 /// sender of the `buffer_collection_id` any capability. The sender must
11737 /// first prove to a receiver that the sender has/had a VMO or has/had a
11738 /// `BufferCollectionToken` to the same collection by sending a handle that
11739 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
11740 /// `buffer_collection_id` value. The receiver should take care to avoid
11741 /// assuming that a sender had a `BufferCollectionToken` in cases where the
11742 /// sender has only proven that the sender had a VMO.
11743 ///
11744 /// - response `buffer_collection_id` This ID is unique per buffer
11745 /// collection per boot. Each buffer is uniquely identified by the
11746 /// `buffer_collection_id` and `buffer_index` together.
11747 GetBufferCollectionId { responder: BufferCollectionTokenGroupGetBufferCollectionIdResponder },
11748 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
11749 /// created after this message to weak, which means that a client's `Node`
11750 /// client end (or a child created after this message) is not alone
11751 /// sufficient to keep allocated VMOs alive.
11752 ///
11753 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
11754 /// `close_weak_asap`.
11755 ///
11756 /// This message is only permitted before the `Node` becomes ready for
11757 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
11758 /// * `BufferCollectionToken`: any time
11759 /// * `BufferCollection`: before `SetConstraints`
11760 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
11761 ///
11762 /// Currently, no conversion from strong `Node` to weak `Node` after ready
11763 /// for allocation is provided, but a client can simulate that by creating
11764 /// an additional `Node` before allocation and setting that additional
11765 /// `Node` to weak, and then potentially at some point later sending
11766 /// `Release` and closing the client end of the client's strong `Node`, but
11767 /// keeping the client's weak `Node`.
11768 ///
11769 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
11770 /// collection failure (all `Node` client end(s) will see
11771 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
11772 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
11773 /// this situation until all `Node`(s) are ready for allocation. For initial
11774 /// allocation to succeed, at least one strong `Node` is required to exist
11775 /// at allocation time, but after that client receives VMO handles, that
11776 /// client can `BufferCollection.Release` and close the client end without
11777 /// causing this type of failure.
11778 ///
11779 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
11780 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
11781 /// separately as appropriate.
11782 SetWeak { control_handle: BufferCollectionTokenGroupControlHandle },
11783 /// This indicates to sysmem that the client is prepared to pay attention to
11784 /// `close_weak_asap`.
11785 ///
11786 /// If sent, this message must be before
11787 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
11788 ///
11789 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
11790 /// send this message before `WaitForAllBuffersAllocated`, or a parent
11791 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
11792 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
11793 /// trigger buffer collection failure.
11794 ///
11795 /// This message is necessary because weak sysmem VMOs have not always been
11796 /// a thing, so older clients are not aware of the need to pay attention to
11797 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
11798 /// sysmem weak VMO handles asap. By having this message and requiring
11799 /// participants to indicate their acceptance of this aspect of the overall
11800 /// protocol, we avoid situations where an older client is delivered a weak
11801 /// VMO without any way for sysmem to get that VMO to close quickly later
11802 /// (and on a per-buffer basis).
11803 ///
11804 /// A participant that doesn't handle `close_weak_asap` and also doesn't
11805 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
11806 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
11807 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
11808 /// same participant has a child/delegate which does retrieve VMOs, that
11809 /// child/delegate will need to send `SetWeakOk` before
11810 /// `WaitForAllBuffersAllocated`.
11811 ///
11812 /// + request `for_child_nodes_also` If present and true, this means direct
11813 /// child nodes of this node created after this message plus all
11814 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
11815 /// those nodes. Any child node of this node that was created before this
11816 /// message is not included. This setting is "sticky" in the sense that a
11817 /// subsequent `SetWeakOk` without this bool set to true does not reset
11818 /// the server-side bool. If this creates a problem for a participant, a
11819 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
11820 /// tokens instead, as appropriate. A participant should only set
11821 /// `for_child_nodes_also` true if the participant can really promise to
11822 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
11823 /// weak VMO handles held by participants holding the corresponding child
11824 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
11825 /// which are using sysmem(1) can be weak, despite the clients of those
11826 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
11827 /// direct way to find out about `close_weak_asap`. This only applies to
11828 /// descendents of this `Node` which are using sysmem(1), not to this
11829 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
11830 /// token, which will fail allocation unless an ancestor of this `Node`
11831 /// specified `for_child_nodes_also` true.
11832 SetWeakOk {
11833 payload: NodeSetWeakOkRequest,
11834 control_handle: BufferCollectionTokenGroupControlHandle,
11835 },
11836 /// The server_end will be closed after this `Node` and any child nodes have
11837 /// have released their buffer counts, making those counts available for
11838 /// reservation by a different `Node` via
11839 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
11840 ///
11841 /// The `Node` buffer counts may not be released until the entire tree of
11842 /// `Node`(s) is closed or failed, because
11843 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
11844 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
11845 /// `Node` buffer counts remain reserved until the orphaned node is later
11846 /// cleaned up.
11847 ///
11848 /// If the `Node` exceeds a fairly large number of attached eventpair server
11849 /// ends, a log message will indicate this and the `Node` (and the
11850 /// appropriate) sub-tree will fail.
11851 ///
11852 /// The `server_end` will remain open when
11853 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
11854 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
11855 /// [`fuchsia.sysmem2/BufferCollection`].
11856 ///
11857 /// This message can also be used with a
11858 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
11859 AttachNodeTracking {
11860 payload: NodeAttachNodeTrackingRequest,
11861 control_handle: BufferCollectionTokenGroupControlHandle,
11862 },
11863 /// Create a child [`fuchsia.sysmem2/BufferCollectionToken`]. Only one child
11864 /// (including its children) will be selected during allocation (or logical
11865 /// allocation).
11866 ///
11867 /// Before passing the client end of this token to
11868 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], completion of
11869 /// [`fuchsia.sysmem2/Node.Sync`] after
11870 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] is required.
11871 /// Or the client can use
11872 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`] which
11873 /// essentially includes the `Sync`.
11874 ///
11875 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
11876 /// fail the group's subtree and close the connection.
11877 ///
11878 /// After all children have been created, send AllChildrenPresent.
11879 ///
11880 /// + request `token_request` The server end of the new token channel.
11881 /// + request `rights_attenuation_mask` If ZX_RIGHT_SAME_RIGHTS, the created
11882 /// token allows the holder to get the same rights to buffers as the
11883 /// parent token (of the group) had. When the value isn't
11884 /// ZX_RIGHT_SAME_RIGHTS, the value is interpretted as a bitmask with 0
11885 /// bits ensuring those rights are attentuated, so 0xFFFFFFFF is a synonym
11886 /// for ZX_RIGHT_SAME_RIGHTS. The value 0 is not allowed and intentionally
11887 /// causes subtree failure.
11888 CreateChild {
11889 payload: BufferCollectionTokenGroupCreateChildRequest,
11890 control_handle: BufferCollectionTokenGroupControlHandle,
11891 },
11892 /// Create 1 or more child tokens at once, synchronously. In contrast to
11893 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`], no
11894 /// [`fuchsia.sysmem2/Node.Sync`] is required before passing the client end
11895 /// of a returned token to
11896 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`].
11897 ///
11898 /// The lower-index child tokens are higher priority (attempted sooner) than
11899 /// higher-index child tokens.
11900 ///
11901 /// As per all child tokens, successful aggregation will choose exactly one
11902 /// child among all created children (across all children created across
11903 /// potentially multiple calls to
11904 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] and
11905 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`]).
11906 ///
11907 /// The maximum permissible total number of children per group, and total
11908 /// number of nodes in an overall tree (from the root) are capped to limits
11909 /// which are not configurable via these protocols.
11910 ///
11911 /// Sending CreateChildrenSync after AllChildrenPresent is not permitted;
11912 /// this will fail the group's subtree and close the connection.
11913 ///
11914 /// After all children have been created, send AllChildrenPresent.
11915 ///
11916 /// + request `rights_attentuation_masks` The size of the
11917 /// `rights_attentuation_masks` determines the number of created child
11918 /// tokens. The value ZX_RIGHT_SAME_RIGHTS doesn't attenuate any rights.
11919 /// The value 0xFFFFFFFF is a synonym for ZX_RIGHT_SAME_RIGHTS. For any
11920 /// other value, each 0 bit in the mask attenuates that right.
11921 /// - response `tokens` The created child tokens.
11922 CreateChildrenSync {
11923 payload: BufferCollectionTokenGroupCreateChildrenSyncRequest,
11924 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder,
11925 },
11926 /// Indicate that no more children will be created.
11927 ///
11928 /// After creating all children, the client should send
11929 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent`] to
11930 /// inform sysmem that no more children will be created, so that sysmem can
11931 /// know when it's ok to start aggregating constraints.
11932 ///
11933 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
11934 /// fail the group's subtree and close the connection.
11935 ///
11936 /// If [`fuchsia.sysmem2/Node.Release`] is to be sent, it should be sent
11937 /// after `AllChildrenPresent`, else failure of the group's subtree will be
11938 /// triggered. This is intentionally not analogous to how `Release` without
11939 /// prior [`fuchsia.sysmem2/BufferCollection.SetConstraints`] doesn't cause
11940 /// subtree failure.
11941 AllChildrenPresent { control_handle: BufferCollectionTokenGroupControlHandle },
11942 /// An interaction was received which does not match any known method.
11943 #[non_exhaustive]
11944 _UnknownMethod {
11945 /// Ordinal of the method that was called.
11946 ordinal: u64,
11947 control_handle: BufferCollectionTokenGroupControlHandle,
11948 method_type: fidl::MethodType,
11949 },
11950}
11951
11952impl BufferCollectionTokenGroupRequest {
11953 #[allow(irrefutable_let_patterns)]
11954 pub fn into_sync(self) -> Option<(BufferCollectionTokenGroupSyncResponder)> {
11955 if let BufferCollectionTokenGroupRequest::Sync { responder } = self {
11956 Some((responder))
11957 } else {
11958 None
11959 }
11960 }
11961
11962 #[allow(irrefutable_let_patterns)]
11963 pub fn into_release(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
11964 if let BufferCollectionTokenGroupRequest::Release { control_handle } = self {
11965 Some((control_handle))
11966 } else {
11967 None
11968 }
11969 }
11970
11971 #[allow(irrefutable_let_patterns)]
11972 pub fn into_set_name(
11973 self,
11974 ) -> Option<(NodeSetNameRequest, BufferCollectionTokenGroupControlHandle)> {
11975 if let BufferCollectionTokenGroupRequest::SetName { payload, control_handle } = self {
11976 Some((payload, control_handle))
11977 } else {
11978 None
11979 }
11980 }
11981
11982 #[allow(irrefutable_let_patterns)]
11983 pub fn into_set_debug_client_info(
11984 self,
11985 ) -> Option<(NodeSetDebugClientInfoRequest, BufferCollectionTokenGroupControlHandle)> {
11986 if let BufferCollectionTokenGroupRequest::SetDebugClientInfo { payload, control_handle } =
11987 self
11988 {
11989 Some((payload, control_handle))
11990 } else {
11991 None
11992 }
11993 }
11994
11995 #[allow(irrefutable_let_patterns)]
11996 pub fn into_set_debug_timeout_log_deadline(
11997 self,
11998 ) -> Option<(NodeSetDebugTimeoutLogDeadlineRequest, BufferCollectionTokenGroupControlHandle)>
11999 {
12000 if let BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {
12001 payload,
12002 control_handle,
12003 } = self
12004 {
12005 Some((payload, control_handle))
12006 } else {
12007 None
12008 }
12009 }
12010
12011 #[allow(irrefutable_let_patterns)]
12012 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
12013 if let BufferCollectionTokenGroupRequest::SetVerboseLogging { control_handle } = self {
12014 Some((control_handle))
12015 } else {
12016 None
12017 }
12018 }
12019
12020 #[allow(irrefutable_let_patterns)]
12021 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGroupGetNodeRefResponder)> {
12022 if let BufferCollectionTokenGroupRequest::GetNodeRef { responder } = self {
12023 Some((responder))
12024 } else {
12025 None
12026 }
12027 }
12028
12029 #[allow(irrefutable_let_patterns)]
12030 pub fn into_is_alternate_for(
12031 self,
12032 ) -> Option<(NodeIsAlternateForRequest, BufferCollectionTokenGroupIsAlternateForResponder)>
12033 {
12034 if let BufferCollectionTokenGroupRequest::IsAlternateFor { payload, responder } = self {
12035 Some((payload, responder))
12036 } else {
12037 None
12038 }
12039 }
12040
12041 #[allow(irrefutable_let_patterns)]
12042 pub fn into_get_buffer_collection_id(
12043 self,
12044 ) -> Option<(BufferCollectionTokenGroupGetBufferCollectionIdResponder)> {
12045 if let BufferCollectionTokenGroupRequest::GetBufferCollectionId { responder } = self {
12046 Some((responder))
12047 } else {
12048 None
12049 }
12050 }
12051
12052 #[allow(irrefutable_let_patterns)]
12053 pub fn into_set_weak(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
12054 if let BufferCollectionTokenGroupRequest::SetWeak { control_handle } = self {
12055 Some((control_handle))
12056 } else {
12057 None
12058 }
12059 }
12060
12061 #[allow(irrefutable_let_patterns)]
12062 pub fn into_set_weak_ok(
12063 self,
12064 ) -> Option<(NodeSetWeakOkRequest, BufferCollectionTokenGroupControlHandle)> {
12065 if let BufferCollectionTokenGroupRequest::SetWeakOk { payload, control_handle } = self {
12066 Some((payload, control_handle))
12067 } else {
12068 None
12069 }
12070 }
12071
12072 #[allow(irrefutable_let_patterns)]
12073 pub fn into_attach_node_tracking(
12074 self,
12075 ) -> Option<(NodeAttachNodeTrackingRequest, BufferCollectionTokenGroupControlHandle)> {
12076 if let BufferCollectionTokenGroupRequest::AttachNodeTracking { payload, control_handle } =
12077 self
12078 {
12079 Some((payload, control_handle))
12080 } else {
12081 None
12082 }
12083 }
12084
12085 #[allow(irrefutable_let_patterns)]
12086 pub fn into_create_child(
12087 self,
12088 ) -> Option<(
12089 BufferCollectionTokenGroupCreateChildRequest,
12090 BufferCollectionTokenGroupControlHandle,
12091 )> {
12092 if let BufferCollectionTokenGroupRequest::CreateChild { payload, control_handle } = self {
12093 Some((payload, control_handle))
12094 } else {
12095 None
12096 }
12097 }
12098
12099 #[allow(irrefutable_let_patterns)]
12100 pub fn into_create_children_sync(
12101 self,
12102 ) -> Option<(
12103 BufferCollectionTokenGroupCreateChildrenSyncRequest,
12104 BufferCollectionTokenGroupCreateChildrenSyncResponder,
12105 )> {
12106 if let BufferCollectionTokenGroupRequest::CreateChildrenSync { payload, responder } = self {
12107 Some((payload, responder))
12108 } else {
12109 None
12110 }
12111 }
12112
12113 #[allow(irrefutable_let_patterns)]
12114 pub fn into_all_children_present(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
12115 if let BufferCollectionTokenGroupRequest::AllChildrenPresent { control_handle } = self {
12116 Some((control_handle))
12117 } else {
12118 None
12119 }
12120 }
12121
12122 /// Name of the method defined in FIDL
12123 pub fn method_name(&self) -> &'static str {
12124 match *self {
12125 BufferCollectionTokenGroupRequest::Sync { .. } => "sync",
12126 BufferCollectionTokenGroupRequest::Release { .. } => "release",
12127 BufferCollectionTokenGroupRequest::SetName { .. } => "set_name",
12128 BufferCollectionTokenGroupRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
12129 BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline { .. } => {
12130 "set_debug_timeout_log_deadline"
12131 }
12132 BufferCollectionTokenGroupRequest::SetVerboseLogging { .. } => "set_verbose_logging",
12133 BufferCollectionTokenGroupRequest::GetNodeRef { .. } => "get_node_ref",
12134 BufferCollectionTokenGroupRequest::IsAlternateFor { .. } => "is_alternate_for",
12135 BufferCollectionTokenGroupRequest::GetBufferCollectionId { .. } => {
12136 "get_buffer_collection_id"
12137 }
12138 BufferCollectionTokenGroupRequest::SetWeak { .. } => "set_weak",
12139 BufferCollectionTokenGroupRequest::SetWeakOk { .. } => "set_weak_ok",
12140 BufferCollectionTokenGroupRequest::AttachNodeTracking { .. } => "attach_node_tracking",
12141 BufferCollectionTokenGroupRequest::CreateChild { .. } => "create_child",
12142 BufferCollectionTokenGroupRequest::CreateChildrenSync { .. } => "create_children_sync",
12143 BufferCollectionTokenGroupRequest::AllChildrenPresent { .. } => "all_children_present",
12144 BufferCollectionTokenGroupRequest::_UnknownMethod {
12145 method_type: fidl::MethodType::OneWay,
12146 ..
12147 } => "unknown one-way method",
12148 BufferCollectionTokenGroupRequest::_UnknownMethod {
12149 method_type: fidl::MethodType::TwoWay,
12150 ..
12151 } => "unknown two-way method",
12152 }
12153 }
12154}
12155
12156#[derive(Debug, Clone)]
12157pub struct BufferCollectionTokenGroupControlHandle {
12158 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
12159}
12160
12161impl BufferCollectionTokenGroupControlHandle {
12162 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
12163 self.inner.shutdown_with_epitaph(status.into())
12164 }
12165}
12166
12167impl fidl::endpoints::ControlHandle for BufferCollectionTokenGroupControlHandle {
12168 fn shutdown(&self) {
12169 self.inner.shutdown()
12170 }
12171
12172 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
12173 self.inner.shutdown_with_epitaph(status)
12174 }
12175
12176 fn is_closed(&self) -> bool {
12177 self.inner.channel().is_closed()
12178 }
12179 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
12180 self.inner.channel().on_closed()
12181 }
12182
12183 #[cfg(target_os = "fuchsia")]
12184 fn signal_peer(
12185 &self,
12186 clear_mask: zx::Signals,
12187 set_mask: zx::Signals,
12188 ) -> Result<(), zx_status::Status> {
12189 use fidl::Peered;
12190 self.inner.channel().signal_peer(clear_mask, set_mask)
12191 }
12192}
12193
12194impl BufferCollectionTokenGroupControlHandle {}
12195
12196#[must_use = "FIDL methods require a response to be sent"]
12197#[derive(Debug)]
12198pub struct BufferCollectionTokenGroupSyncResponder {
12199 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
12200 tx_id: u32,
12201}
12202
12203/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
12204/// if the responder is dropped without sending a response, so that the client
12205/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
12206impl std::ops::Drop for BufferCollectionTokenGroupSyncResponder {
12207 fn drop(&mut self) {
12208 self.control_handle.shutdown();
12209 // Safety: drops once, never accessed again
12210 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12211 }
12212}
12213
12214impl fidl::endpoints::Responder for BufferCollectionTokenGroupSyncResponder {
12215 type ControlHandle = BufferCollectionTokenGroupControlHandle;
12216
12217 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
12218 &self.control_handle
12219 }
12220
12221 fn drop_without_shutdown(mut self) {
12222 // Safety: drops once, never accessed again due to mem::forget
12223 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12224 // Prevent Drop from running (which would shut down the channel)
12225 std::mem::forget(self);
12226 }
12227}
12228
12229impl BufferCollectionTokenGroupSyncResponder {
12230 /// Sends a response to the FIDL transaction.
12231 ///
12232 /// Sets the channel to shutdown if an error occurs.
12233 pub fn send(self) -> Result<(), fidl::Error> {
12234 let _result = self.send_raw();
12235 if _result.is_err() {
12236 self.control_handle.shutdown();
12237 }
12238 self.drop_without_shutdown();
12239 _result
12240 }
12241
12242 /// Similar to "send" but does not shutdown the channel if an error occurs.
12243 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
12244 let _result = self.send_raw();
12245 self.drop_without_shutdown();
12246 _result
12247 }
12248
12249 fn send_raw(&self) -> Result<(), fidl::Error> {
12250 self.control_handle.inner.send::<fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>>(
12251 fidl::encoding::Flexible::new(()),
12252 self.tx_id,
12253 0x11ac2555cf575b54,
12254 fidl::encoding::DynamicFlags::FLEXIBLE,
12255 )
12256 }
12257}
12258
12259#[must_use = "FIDL methods require a response to be sent"]
12260#[derive(Debug)]
12261pub struct BufferCollectionTokenGroupGetNodeRefResponder {
12262 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
12263 tx_id: u32,
12264}
12265
12266/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
12267/// if the responder is dropped without sending a response, so that the client
12268/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
12269impl std::ops::Drop for BufferCollectionTokenGroupGetNodeRefResponder {
12270 fn drop(&mut self) {
12271 self.control_handle.shutdown();
12272 // Safety: drops once, never accessed again
12273 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12274 }
12275}
12276
12277impl fidl::endpoints::Responder for BufferCollectionTokenGroupGetNodeRefResponder {
12278 type ControlHandle = BufferCollectionTokenGroupControlHandle;
12279
12280 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
12281 &self.control_handle
12282 }
12283
12284 fn drop_without_shutdown(mut self) {
12285 // Safety: drops once, never accessed again due to mem::forget
12286 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12287 // Prevent Drop from running (which would shut down the channel)
12288 std::mem::forget(self);
12289 }
12290}
12291
12292impl BufferCollectionTokenGroupGetNodeRefResponder {
12293 /// Sends a response to the FIDL transaction.
12294 ///
12295 /// Sets the channel to shutdown if an error occurs.
12296 pub fn send(self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
12297 let _result = self.send_raw(payload);
12298 if _result.is_err() {
12299 self.control_handle.shutdown();
12300 }
12301 self.drop_without_shutdown();
12302 _result
12303 }
12304
12305 /// Similar to "send" but does not shutdown the channel if an error occurs.
12306 pub fn send_no_shutdown_on_err(
12307 self,
12308 mut payload: NodeGetNodeRefResponse,
12309 ) -> Result<(), fidl::Error> {
12310 let _result = self.send_raw(payload);
12311 self.drop_without_shutdown();
12312 _result
12313 }
12314
12315 fn send_raw(&self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
12316 self.control_handle.inner.send::<fidl::encoding::FlexibleType<NodeGetNodeRefResponse>>(
12317 fidl::encoding::Flexible::new(&mut payload),
12318 self.tx_id,
12319 0x5b3d0e51614df053,
12320 fidl::encoding::DynamicFlags::FLEXIBLE,
12321 )
12322 }
12323}
12324
12325#[must_use = "FIDL methods require a response to be sent"]
12326#[derive(Debug)]
12327pub struct BufferCollectionTokenGroupIsAlternateForResponder {
12328 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
12329 tx_id: u32,
12330}
12331
12332/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
12333/// if the responder is dropped without sending a response, so that the client
12334/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
12335impl std::ops::Drop for BufferCollectionTokenGroupIsAlternateForResponder {
12336 fn drop(&mut self) {
12337 self.control_handle.shutdown();
12338 // Safety: drops once, never accessed again
12339 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12340 }
12341}
12342
12343impl fidl::endpoints::Responder for BufferCollectionTokenGroupIsAlternateForResponder {
12344 type ControlHandle = BufferCollectionTokenGroupControlHandle;
12345
12346 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
12347 &self.control_handle
12348 }
12349
12350 fn drop_without_shutdown(mut self) {
12351 // Safety: drops once, never accessed again due to mem::forget
12352 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12353 // Prevent Drop from running (which would shut down the channel)
12354 std::mem::forget(self);
12355 }
12356}
12357
12358impl BufferCollectionTokenGroupIsAlternateForResponder {
12359 /// Sends a response to the FIDL transaction.
12360 ///
12361 /// Sets the channel to shutdown if an error occurs.
12362 pub fn send(
12363 self,
12364 mut result: Result<&NodeIsAlternateForResponse, Error>,
12365 ) -> Result<(), fidl::Error> {
12366 let _result = self.send_raw(result);
12367 if _result.is_err() {
12368 self.control_handle.shutdown();
12369 }
12370 self.drop_without_shutdown();
12371 _result
12372 }
12373
12374 /// Similar to "send" but does not shutdown the channel if an error occurs.
12375 pub fn send_no_shutdown_on_err(
12376 self,
12377 mut result: Result<&NodeIsAlternateForResponse, Error>,
12378 ) -> Result<(), fidl::Error> {
12379 let _result = self.send_raw(result);
12380 self.drop_without_shutdown();
12381 _result
12382 }
12383
12384 fn send_raw(
12385 &self,
12386 mut result: Result<&NodeIsAlternateForResponse, Error>,
12387 ) -> Result<(), fidl::Error> {
12388 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
12389 NodeIsAlternateForResponse,
12390 Error,
12391 >>(
12392 fidl::encoding::FlexibleResult::new(result),
12393 self.tx_id,
12394 0x3a58e00157e0825,
12395 fidl::encoding::DynamicFlags::FLEXIBLE,
12396 )
12397 }
12398}
12399
12400#[must_use = "FIDL methods require a response to be sent"]
12401#[derive(Debug)]
12402pub struct BufferCollectionTokenGroupGetBufferCollectionIdResponder {
12403 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
12404 tx_id: u32,
12405}
12406
12407/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
12408/// if the responder is dropped without sending a response, so that the client
12409/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
12410impl std::ops::Drop for BufferCollectionTokenGroupGetBufferCollectionIdResponder {
12411 fn drop(&mut self) {
12412 self.control_handle.shutdown();
12413 // Safety: drops once, never accessed again
12414 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12415 }
12416}
12417
12418impl fidl::endpoints::Responder for BufferCollectionTokenGroupGetBufferCollectionIdResponder {
12419 type ControlHandle = BufferCollectionTokenGroupControlHandle;
12420
12421 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
12422 &self.control_handle
12423 }
12424
12425 fn drop_without_shutdown(mut self) {
12426 // Safety: drops once, never accessed again due to mem::forget
12427 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12428 // Prevent Drop from running (which would shut down the channel)
12429 std::mem::forget(self);
12430 }
12431}
12432
12433impl BufferCollectionTokenGroupGetBufferCollectionIdResponder {
12434 /// Sends a response to the FIDL transaction.
12435 ///
12436 /// Sets the channel to shutdown if an error occurs.
12437 pub fn send(self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
12438 let _result = self.send_raw(payload);
12439 if _result.is_err() {
12440 self.control_handle.shutdown();
12441 }
12442 self.drop_without_shutdown();
12443 _result
12444 }
12445
12446 /// Similar to "send" but does not shutdown the channel if an error occurs.
12447 pub fn send_no_shutdown_on_err(
12448 self,
12449 mut payload: &NodeGetBufferCollectionIdResponse,
12450 ) -> Result<(), fidl::Error> {
12451 let _result = self.send_raw(payload);
12452 self.drop_without_shutdown();
12453 _result
12454 }
12455
12456 fn send_raw(&self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
12457 self.control_handle
12458 .inner
12459 .send::<fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>>(
12460 fidl::encoding::Flexible::new(payload),
12461 self.tx_id,
12462 0x77d19a494b78ba8c,
12463 fidl::encoding::DynamicFlags::FLEXIBLE,
12464 )
12465 }
12466}
12467
12468#[must_use = "FIDL methods require a response to be sent"]
12469#[derive(Debug)]
12470pub struct BufferCollectionTokenGroupCreateChildrenSyncResponder {
12471 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
12472 tx_id: u32,
12473}
12474
12475/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
12476/// if the responder is dropped without sending a response, so that the client
12477/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
12478impl std::ops::Drop for BufferCollectionTokenGroupCreateChildrenSyncResponder {
12479 fn drop(&mut self) {
12480 self.control_handle.shutdown();
12481 // Safety: drops once, never accessed again
12482 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12483 }
12484}
12485
12486impl fidl::endpoints::Responder for BufferCollectionTokenGroupCreateChildrenSyncResponder {
12487 type ControlHandle = BufferCollectionTokenGroupControlHandle;
12488
12489 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
12490 &self.control_handle
12491 }
12492
12493 fn drop_without_shutdown(mut self) {
12494 // Safety: drops once, never accessed again due to mem::forget
12495 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12496 // Prevent Drop from running (which would shut down the channel)
12497 std::mem::forget(self);
12498 }
12499}
12500
12501impl BufferCollectionTokenGroupCreateChildrenSyncResponder {
12502 /// Sends a response to the FIDL transaction.
12503 ///
12504 /// Sets the channel to shutdown if an error occurs.
12505 pub fn send(
12506 self,
12507 mut payload: BufferCollectionTokenGroupCreateChildrenSyncResponse,
12508 ) -> Result<(), fidl::Error> {
12509 let _result = self.send_raw(payload);
12510 if _result.is_err() {
12511 self.control_handle.shutdown();
12512 }
12513 self.drop_without_shutdown();
12514 _result
12515 }
12516
12517 /// Similar to "send" but does not shutdown the channel if an error occurs.
12518 pub fn send_no_shutdown_on_err(
12519 self,
12520 mut payload: BufferCollectionTokenGroupCreateChildrenSyncResponse,
12521 ) -> Result<(), fidl::Error> {
12522 let _result = self.send_raw(payload);
12523 self.drop_without_shutdown();
12524 _result
12525 }
12526
12527 fn send_raw(
12528 &self,
12529 mut payload: BufferCollectionTokenGroupCreateChildrenSyncResponse,
12530 ) -> Result<(), fidl::Error> {
12531 self.control_handle.inner.send::<fidl::encoding::FlexibleType<
12532 BufferCollectionTokenGroupCreateChildrenSyncResponse,
12533 >>(
12534 fidl::encoding::Flexible::new(&mut payload),
12535 self.tx_id,
12536 0x15dea448c536070a,
12537 fidl::encoding::DynamicFlags::FLEXIBLE,
12538 )
12539 }
12540}
12541
12542#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
12543pub struct NodeMarker;
12544
12545impl fidl::endpoints::ProtocolMarker for NodeMarker {
12546 type Proxy = NodeProxy;
12547 type RequestStream = NodeRequestStream;
12548 #[cfg(target_os = "fuchsia")]
12549 type SynchronousProxy = NodeSynchronousProxy;
12550
12551 const DEBUG_NAME: &'static str = "(anonymous) Node";
12552}
12553pub type NodeIsAlternateForResult = Result<NodeIsAlternateForResponse, Error>;
12554
12555pub trait NodeProxyInterface: Send + Sync {
12556 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
12557 fn r#sync(&self) -> Self::SyncResponseFut;
12558 fn r#release(&self) -> Result<(), fidl::Error>;
12559 fn r#set_name(&self, payload: &NodeSetNameRequest) -> Result<(), fidl::Error>;
12560 fn r#set_debug_client_info(
12561 &self,
12562 payload: &NodeSetDebugClientInfoRequest,
12563 ) -> Result<(), fidl::Error>;
12564 fn r#set_debug_timeout_log_deadline(
12565 &self,
12566 payload: &NodeSetDebugTimeoutLogDeadlineRequest,
12567 ) -> Result<(), fidl::Error>;
12568 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
12569 type GetNodeRefResponseFut: std::future::Future<Output = Result<NodeGetNodeRefResponse, fidl::Error>>
12570 + Send;
12571 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
12572 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
12573 + Send;
12574 fn r#is_alternate_for(
12575 &self,
12576 payload: NodeIsAlternateForRequest,
12577 ) -> Self::IsAlternateForResponseFut;
12578 type GetBufferCollectionIdResponseFut: std::future::Future<Output = Result<NodeGetBufferCollectionIdResponse, fidl::Error>>
12579 + Send;
12580 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut;
12581 fn r#set_weak(&self) -> Result<(), fidl::Error>;
12582 fn r#set_weak_ok(&self, payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error>;
12583 fn r#attach_node_tracking(
12584 &self,
12585 payload: NodeAttachNodeTrackingRequest,
12586 ) -> Result<(), fidl::Error>;
12587}
12588#[derive(Debug)]
12589#[cfg(target_os = "fuchsia")]
12590pub struct NodeSynchronousProxy {
12591 client: fidl::client::sync::Client,
12592}
12593
12594#[cfg(target_os = "fuchsia")]
12595impl fidl::endpoints::SynchronousProxy for NodeSynchronousProxy {
12596 type Proxy = NodeProxy;
12597 type Protocol = NodeMarker;
12598
12599 fn from_channel(inner: fidl::Channel) -> Self {
12600 Self::new(inner)
12601 }
12602
12603 fn into_channel(self) -> fidl::Channel {
12604 self.client.into_channel()
12605 }
12606
12607 fn as_channel(&self) -> &fidl::Channel {
12608 self.client.as_channel()
12609 }
12610}
12611
12612#[cfg(target_os = "fuchsia")]
12613impl NodeSynchronousProxy {
12614 pub fn new(channel: fidl::Channel) -> Self {
12615 Self { client: fidl::client::sync::Client::new(channel) }
12616 }
12617
12618 pub fn into_channel(self) -> fidl::Channel {
12619 self.client.into_channel()
12620 }
12621
12622 /// Waits until an event arrives and returns it. It is safe for other
12623 /// threads to make concurrent requests while waiting for an event.
12624 pub fn wait_for_event(&self, deadline: zx::MonotonicInstant) -> Result<NodeEvent, fidl::Error> {
12625 NodeEvent::decode(self.client.wait_for_event::<NodeMarker>(deadline)?)
12626 }
12627
12628 /// Ensure that previous messages have been received server side. This is
12629 /// particularly useful after previous messages that created new tokens,
12630 /// because a token must be known to the sysmem server before sending the
12631 /// token to another participant.
12632 ///
12633 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
12634 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
12635 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
12636 /// to mitigate the possibility of a hostile/fake
12637 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
12638 /// Another way is to pass the token to
12639 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
12640 /// the token as part of exchanging it for a
12641 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
12642 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
12643 /// of stalling.
12644 ///
12645 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
12646 /// and then starting and completing a `Sync`, it's then safe to send the
12647 /// `BufferCollectionToken` client ends to other participants knowing the
12648 /// server will recognize the tokens when they're sent by the other
12649 /// participants to sysmem in a
12650 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
12651 /// efficient way to create tokens while avoiding unnecessary round trips.
12652 ///
12653 /// Other options include waiting for each
12654 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
12655 /// individually (using separate call to `Sync` after each), or calling
12656 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
12657 /// converted to a `BufferCollection` via
12658 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
12659 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
12660 /// the sync step and can create multiple tokens at once.
12661 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
12662 let _response = self.client.send_query::<
12663 fidl::encoding::EmptyPayload,
12664 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
12665 NodeMarker,
12666 >(
12667 (),
12668 0x11ac2555cf575b54,
12669 fidl::encoding::DynamicFlags::FLEXIBLE,
12670 ___deadline,
12671 )?
12672 .into_result::<NodeMarker>("sync")?;
12673 Ok(_response)
12674 }
12675
12676 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
12677 ///
12678 /// Normally a participant will convert a `BufferCollectionToken` into a
12679 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
12680 /// `Release` via the token (and then close the channel immediately or
12681 /// shortly later in response to server closing the server end), which
12682 /// avoids causing buffer collection failure. Without a prior `Release`,
12683 /// closing the `BufferCollectionToken` client end will cause buffer
12684 /// collection failure.
12685 ///
12686 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
12687 ///
12688 /// By default the server handles unexpected closure of a
12689 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
12690 /// first) by failing the buffer collection. Partly this is to expedite
12691 /// closing VMO handles to reclaim memory when any participant fails. If a
12692 /// participant would like to cleanly close a `BufferCollection` without
12693 /// causing buffer collection failure, the participant can send `Release`
12694 /// before closing the `BufferCollection` client end. The `Release` can
12695 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
12696 /// buffer collection won't require constraints from this node in order to
12697 /// allocate. If after `SetConstraints`, the constraints are retained and
12698 /// aggregated, despite the lack of `BufferCollection` connection at the
12699 /// time of constraints aggregation.
12700 ///
12701 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
12702 ///
12703 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
12704 /// end (without `Release` first) will trigger failure of the buffer
12705 /// collection. To close a `BufferCollectionTokenGroup` channel without
12706 /// failing the buffer collection, ensure that AllChildrenPresent() has been
12707 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
12708 /// client end.
12709 ///
12710 /// If `Release` occurs before
12711 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
12712 /// buffer collection will fail (triggered by reception of `Release` without
12713 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
12714 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
12715 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
12716 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
12717 /// close requires `AllChildrenPresent` (if not already sent), then
12718 /// `Release`, then close client end.
12719 ///
12720 /// If `Release` occurs after `AllChildrenPresent`, the children and all
12721 /// their constraints remain intact (just as they would if the
12722 /// `BufferCollectionTokenGroup` channel had remained open), and the client
12723 /// end close doesn't trigger buffer collection failure.
12724 ///
12725 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
12726 ///
12727 /// For brevity, the per-channel-protocol paragraphs above ignore the
12728 /// separate failure domain created by
12729 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
12730 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
12731 /// unexpectedly closes (without `Release` first) and that client end is
12732 /// under a failure domain, instead of failing the whole buffer collection,
12733 /// the failure domain is failed, but the buffer collection itself is
12734 /// isolated from failure of the failure domain. Such failure domains can be
12735 /// nested, in which case only the inner-most failure domain in which the
12736 /// `Node` resides fails.
12737 pub fn r#release(&self) -> Result<(), fidl::Error> {
12738 self.client.send::<fidl::encoding::EmptyPayload>(
12739 (),
12740 0x6a5cae7d6d6e04c6,
12741 fidl::encoding::DynamicFlags::FLEXIBLE,
12742 )
12743 }
12744
12745 /// Set a name for VMOs in this buffer collection.
12746 ///
12747 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
12748 /// will be truncated to fit. The name of the vmo will be suffixed with the
12749 /// buffer index within the collection (if the suffix fits within
12750 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
12751 /// listed in the inspect data.
12752 ///
12753 /// The name only affects VMOs allocated after the name is set; this call
12754 /// does not rename existing VMOs. If multiple clients set different names
12755 /// then the larger priority value will win. Setting a new name with the
12756 /// same priority as a prior name doesn't change the name.
12757 ///
12758 /// All table fields are currently required.
12759 ///
12760 /// + request `priority` The name is only set if this is the first `SetName`
12761 /// or if `priority` is greater than any previous `priority` value in
12762 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
12763 /// + request `name` The name for VMOs created under this buffer collection.
12764 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
12765 self.client.send::<NodeSetNameRequest>(
12766 payload,
12767 0xb41f1624f48c1e9,
12768 fidl::encoding::DynamicFlags::FLEXIBLE,
12769 )
12770 }
12771
12772 /// Set information about the current client that can be used by sysmem to
12773 /// help diagnose leaking memory and allocation stalls waiting for a
12774 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
12775 ///
12776 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
12777 /// `Node`(s) derived from this `Node`, unless overriden by
12778 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
12779 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
12780 ///
12781 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
12782 /// `Allocator` is the most efficient way to ensure that all
12783 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
12784 /// set, and is also more efficient than separately sending the same debug
12785 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
12786 /// created [`fuchsia.sysmem2/Node`].
12787 ///
12788 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
12789 /// indicate which client is closing their channel first, leading to subtree
12790 /// failure (which can be normal if the purpose of the subtree is over, but
12791 /// if happening earlier than expected, the client-channel-specific name can
12792 /// help diagnose where the failure is first coming from, from sysmem's
12793 /// point of view).
12794 ///
12795 /// All table fields are currently required.
12796 ///
12797 /// + request `name` This can be an arbitrary string, but the current
12798 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
12799 /// + request `id` This can be an arbitrary id, but the current process ID
12800 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
12801 pub fn r#set_debug_client_info(
12802 &self,
12803 mut payload: &NodeSetDebugClientInfoRequest,
12804 ) -> Result<(), fidl::Error> {
12805 self.client.send::<NodeSetDebugClientInfoRequest>(
12806 payload,
12807 0x5cde8914608d99b1,
12808 fidl::encoding::DynamicFlags::FLEXIBLE,
12809 )
12810 }
12811
12812 /// Sysmem logs a warning if sysmem hasn't seen
12813 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
12814 /// within 5 seconds after creation of a new collection.
12815 ///
12816 /// Clients can call this method to change when the log is printed. If
12817 /// multiple client set the deadline, it's unspecified which deadline will
12818 /// take effect.
12819 ///
12820 /// In most cases the default works well.
12821 ///
12822 /// All table fields are currently required.
12823 ///
12824 /// + request `deadline` The time at which sysmem will start trying to log
12825 /// the warning, unless all constraints are with sysmem by then.
12826 pub fn r#set_debug_timeout_log_deadline(
12827 &self,
12828 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
12829 ) -> Result<(), fidl::Error> {
12830 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
12831 payload,
12832 0x716b0af13d5c0806,
12833 fidl::encoding::DynamicFlags::FLEXIBLE,
12834 )
12835 }
12836
12837 /// This enables verbose logging for the buffer collection.
12838 ///
12839 /// Verbose logging includes constraints set via
12840 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
12841 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
12842 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
12843 /// the tree of `Node`(s).
12844 ///
12845 /// Normally sysmem prints only a single line complaint when aggregation
12846 /// fails, with just the specific detailed reason that aggregation failed,
12847 /// with little surrounding context. While this is often enough to diagnose
12848 /// a problem if only a small change was made and everything was working
12849 /// before the small change, it's often not particularly helpful for getting
12850 /// a new buffer collection to work for the first time. Especially with
12851 /// more complex trees of nodes, involving things like
12852 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
12853 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
12854 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
12855 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
12856 /// looks like and why it's failing a logical allocation, or why a tree or
12857 /// subtree is failing sooner than expected.
12858 ///
12859 /// The intent of the extra logging is to be acceptable from a performance
12860 /// point of view, under the assumption that verbose logging is only enabled
12861 /// on a low number of buffer collections. If we're not tracking down a bug,
12862 /// we shouldn't send this message.
12863 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
12864 self.client.send::<fidl::encoding::EmptyPayload>(
12865 (),
12866 0x5209c77415b4dfad,
12867 fidl::encoding::DynamicFlags::FLEXIBLE,
12868 )
12869 }
12870
12871 /// This gets a handle that can be used as a parameter to
12872 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
12873 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
12874 /// client obtained this handle from this `Node`.
12875 ///
12876 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
12877 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
12878 /// despite the two calls typically being on different channels.
12879 ///
12880 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
12881 ///
12882 /// All table fields are currently required.
12883 ///
12884 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
12885 /// different `Node` channel, to prove that the client obtained the handle
12886 /// from this `Node`.
12887 pub fn r#get_node_ref(
12888 &self,
12889 ___deadline: zx::MonotonicInstant,
12890 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
12891 let _response = self.client.send_query::<
12892 fidl::encoding::EmptyPayload,
12893 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
12894 NodeMarker,
12895 >(
12896 (),
12897 0x5b3d0e51614df053,
12898 fidl::encoding::DynamicFlags::FLEXIBLE,
12899 ___deadline,
12900 )?
12901 .into_result::<NodeMarker>("get_node_ref")?;
12902 Ok(_response)
12903 }
12904
12905 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
12906 /// rooted at a different child token of a common parent
12907 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
12908 /// passed-in `node_ref`.
12909 ///
12910 /// This call is for assisting with admission control de-duplication, and
12911 /// with debugging.
12912 ///
12913 /// The `node_ref` must be obtained using
12914 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
12915 ///
12916 /// The `node_ref` can be a duplicated handle; it's not necessary to call
12917 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
12918 ///
12919 /// If a calling token may not actually be a valid token at all due to a
12920 /// potentially hostile/untrusted provider of the token, call
12921 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
12922 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
12923 /// never responds due to a calling token not being a real token (not really
12924 /// talking to sysmem). Another option is to call
12925 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
12926 /// which also validates the token along with converting it to a
12927 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
12928 ///
12929 /// All table fields are currently required.
12930 ///
12931 /// - response `is_alternate`
12932 /// - true: The first parent node in common between the calling node and
12933 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
12934 /// that the calling `Node` and the `node_ref` `Node` will not have both
12935 /// their constraints apply - rather sysmem will choose one or the other
12936 /// of the constraints - never both. This is because only one child of
12937 /// a `BufferCollectionTokenGroup` is selected during logical
12938 /// allocation, with only that one child's subtree contributing to
12939 /// constraints aggregation.
12940 /// - false: The first parent node in common between the calling `Node`
12941 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
12942 /// Currently, this means the first parent node in common is a
12943 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
12944 /// `Release`ed). This means that the calling `Node` and the `node_ref`
12945 /// `Node` may have both their constraints apply during constraints
12946 /// aggregation of the logical allocation, if both `Node`(s) are
12947 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
12948 /// this case, there is no `BufferCollectionTokenGroup` that will
12949 /// directly prevent the two `Node`(s) from both being selected and
12950 /// their constraints both aggregated, but even when false, one or both
12951 /// `Node`(s) may still be eliminated from consideration if one or both
12952 /// `Node`(s) has a direct or indirect parent
12953 /// `BufferCollectionTokenGroup` which selects a child subtree other
12954 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
12955 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
12956 /// associated with the same buffer collection as the calling `Node`.
12957 /// Another reason for this error is if the `node_ref` is an
12958 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
12959 /// a real `node_ref` obtained from `GetNodeRef`.
12960 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
12961 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
12962 /// the needed rights expected on a real `node_ref`.
12963 /// * No other failing status codes are returned by this call. However,
12964 /// sysmem may add additional codes in future, so the client should have
12965 /// sensible default handling for any failing status code.
12966 pub fn r#is_alternate_for(
12967 &self,
12968 mut payload: NodeIsAlternateForRequest,
12969 ___deadline: zx::MonotonicInstant,
12970 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
12971 let _response = self.client.send_query::<
12972 NodeIsAlternateForRequest,
12973 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
12974 NodeMarker,
12975 >(
12976 &mut payload,
12977 0x3a58e00157e0825,
12978 fidl::encoding::DynamicFlags::FLEXIBLE,
12979 ___deadline,
12980 )?
12981 .into_result::<NodeMarker>("is_alternate_for")?;
12982 Ok(_response.map(|x| x))
12983 }
12984
12985 /// Get the buffer collection ID. This ID is also available from
12986 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
12987 /// within the collection).
12988 ///
12989 /// This call is mainly useful in situations where we can't convey a
12990 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
12991 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
12992 /// handle, which can be joined back up with a `BufferCollection` client end
12993 /// that was created via a different path. Prefer to convey a
12994 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
12995 ///
12996 /// Trusting a `buffer_collection_id` value from a source other than sysmem
12997 /// is analogous to trusting a koid value from a source other than zircon.
12998 /// Both should be avoided unless really necessary, and both require
12999 /// caution. In some situations it may be reasonable to refer to a
13000 /// pre-established `BufferCollection` by `buffer_collection_id` via a
13001 /// protocol for efficiency reasons, but an incoming value purporting to be
13002 /// a `buffer_collection_id` is not sufficient alone to justify granting the
13003 /// sender of the `buffer_collection_id` any capability. The sender must
13004 /// first prove to a receiver that the sender has/had a VMO or has/had a
13005 /// `BufferCollectionToken` to the same collection by sending a handle that
13006 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
13007 /// `buffer_collection_id` value. The receiver should take care to avoid
13008 /// assuming that a sender had a `BufferCollectionToken` in cases where the
13009 /// sender has only proven that the sender had a VMO.
13010 ///
13011 /// - response `buffer_collection_id` This ID is unique per buffer
13012 /// collection per boot. Each buffer is uniquely identified by the
13013 /// `buffer_collection_id` and `buffer_index` together.
13014 pub fn r#get_buffer_collection_id(
13015 &self,
13016 ___deadline: zx::MonotonicInstant,
13017 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
13018 let _response = self.client.send_query::<
13019 fidl::encoding::EmptyPayload,
13020 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
13021 NodeMarker,
13022 >(
13023 (),
13024 0x77d19a494b78ba8c,
13025 fidl::encoding::DynamicFlags::FLEXIBLE,
13026 ___deadline,
13027 )?
13028 .into_result::<NodeMarker>("get_buffer_collection_id")?;
13029 Ok(_response)
13030 }
13031
13032 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
13033 /// created after this message to weak, which means that a client's `Node`
13034 /// client end (or a child created after this message) is not alone
13035 /// sufficient to keep allocated VMOs alive.
13036 ///
13037 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
13038 /// `close_weak_asap`.
13039 ///
13040 /// This message is only permitted before the `Node` becomes ready for
13041 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
13042 /// * `BufferCollectionToken`: any time
13043 /// * `BufferCollection`: before `SetConstraints`
13044 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
13045 ///
13046 /// Currently, no conversion from strong `Node` to weak `Node` after ready
13047 /// for allocation is provided, but a client can simulate that by creating
13048 /// an additional `Node` before allocation and setting that additional
13049 /// `Node` to weak, and then potentially at some point later sending
13050 /// `Release` and closing the client end of the client's strong `Node`, but
13051 /// keeping the client's weak `Node`.
13052 ///
13053 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
13054 /// collection failure (all `Node` client end(s) will see
13055 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
13056 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
13057 /// this situation until all `Node`(s) are ready for allocation. For initial
13058 /// allocation to succeed, at least one strong `Node` is required to exist
13059 /// at allocation time, but after that client receives VMO handles, that
13060 /// client can `BufferCollection.Release` and close the client end without
13061 /// causing this type of failure.
13062 ///
13063 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
13064 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
13065 /// separately as appropriate.
13066 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
13067 self.client.send::<fidl::encoding::EmptyPayload>(
13068 (),
13069 0x22dd3ea514eeffe1,
13070 fidl::encoding::DynamicFlags::FLEXIBLE,
13071 )
13072 }
13073
13074 /// This indicates to sysmem that the client is prepared to pay attention to
13075 /// `close_weak_asap`.
13076 ///
13077 /// If sent, this message must be before
13078 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
13079 ///
13080 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
13081 /// send this message before `WaitForAllBuffersAllocated`, or a parent
13082 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
13083 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
13084 /// trigger buffer collection failure.
13085 ///
13086 /// This message is necessary because weak sysmem VMOs have not always been
13087 /// a thing, so older clients are not aware of the need to pay attention to
13088 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
13089 /// sysmem weak VMO handles asap. By having this message and requiring
13090 /// participants to indicate their acceptance of this aspect of the overall
13091 /// protocol, we avoid situations where an older client is delivered a weak
13092 /// VMO without any way for sysmem to get that VMO to close quickly later
13093 /// (and on a per-buffer basis).
13094 ///
13095 /// A participant that doesn't handle `close_weak_asap` and also doesn't
13096 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
13097 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
13098 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
13099 /// same participant has a child/delegate which does retrieve VMOs, that
13100 /// child/delegate will need to send `SetWeakOk` before
13101 /// `WaitForAllBuffersAllocated`.
13102 ///
13103 /// + request `for_child_nodes_also` If present and true, this means direct
13104 /// child nodes of this node created after this message plus all
13105 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
13106 /// those nodes. Any child node of this node that was created before this
13107 /// message is not included. This setting is "sticky" in the sense that a
13108 /// subsequent `SetWeakOk` without this bool set to true does not reset
13109 /// the server-side bool. If this creates a problem for a participant, a
13110 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
13111 /// tokens instead, as appropriate. A participant should only set
13112 /// `for_child_nodes_also` true if the participant can really promise to
13113 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
13114 /// weak VMO handles held by participants holding the corresponding child
13115 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
13116 /// which are using sysmem(1) can be weak, despite the clients of those
13117 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
13118 /// direct way to find out about `close_weak_asap`. This only applies to
13119 /// descendents of this `Node` which are using sysmem(1), not to this
13120 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
13121 /// token, which will fail allocation unless an ancestor of this `Node`
13122 /// specified `for_child_nodes_also` true.
13123 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
13124 self.client.send::<NodeSetWeakOkRequest>(
13125 &mut payload,
13126 0x38a44fc4d7724be9,
13127 fidl::encoding::DynamicFlags::FLEXIBLE,
13128 )
13129 }
13130
13131 /// The server_end will be closed after this `Node` and any child nodes have
13132 /// have released their buffer counts, making those counts available for
13133 /// reservation by a different `Node` via
13134 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
13135 ///
13136 /// The `Node` buffer counts may not be released until the entire tree of
13137 /// `Node`(s) is closed or failed, because
13138 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
13139 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
13140 /// `Node` buffer counts remain reserved until the orphaned node is later
13141 /// cleaned up.
13142 ///
13143 /// If the `Node` exceeds a fairly large number of attached eventpair server
13144 /// ends, a log message will indicate this and the `Node` (and the
13145 /// appropriate) sub-tree will fail.
13146 ///
13147 /// The `server_end` will remain open when
13148 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
13149 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
13150 /// [`fuchsia.sysmem2/BufferCollection`].
13151 ///
13152 /// This message can also be used with a
13153 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
13154 pub fn r#attach_node_tracking(
13155 &self,
13156 mut payload: NodeAttachNodeTrackingRequest,
13157 ) -> Result<(), fidl::Error> {
13158 self.client.send::<NodeAttachNodeTrackingRequest>(
13159 &mut payload,
13160 0x3f22f2a293d3cdac,
13161 fidl::encoding::DynamicFlags::FLEXIBLE,
13162 )
13163 }
13164}
13165
13166#[cfg(target_os = "fuchsia")]
13167impl From<NodeSynchronousProxy> for zx::NullableHandle {
13168 fn from(value: NodeSynchronousProxy) -> Self {
13169 value.into_channel().into()
13170 }
13171}
13172
13173#[cfg(target_os = "fuchsia")]
13174impl From<fidl::Channel> for NodeSynchronousProxy {
13175 fn from(value: fidl::Channel) -> Self {
13176 Self::new(value)
13177 }
13178}
13179
13180#[cfg(target_os = "fuchsia")]
13181impl fidl::endpoints::FromClient for NodeSynchronousProxy {
13182 type Protocol = NodeMarker;
13183
13184 fn from_client(value: fidl::endpoints::ClientEnd<NodeMarker>) -> Self {
13185 Self::new(value.into_channel())
13186 }
13187}
13188
13189#[derive(Debug, Clone)]
13190pub struct NodeProxy {
13191 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
13192}
13193
13194impl fidl::endpoints::Proxy for NodeProxy {
13195 type Protocol = NodeMarker;
13196
13197 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
13198 Self::new(inner)
13199 }
13200
13201 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
13202 self.client.into_channel().map_err(|client| Self { client })
13203 }
13204
13205 fn as_channel(&self) -> &::fidl::AsyncChannel {
13206 self.client.as_channel()
13207 }
13208}
13209
13210impl NodeProxy {
13211 /// Create a new Proxy for fuchsia.sysmem2/Node.
13212 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
13213 let protocol_name = <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
13214 Self { client: fidl::client::Client::new(channel, protocol_name) }
13215 }
13216
13217 /// Get a Stream of events from the remote end of the protocol.
13218 ///
13219 /// # Panics
13220 ///
13221 /// Panics if the event stream was already taken.
13222 pub fn take_event_stream(&self) -> NodeEventStream {
13223 NodeEventStream { event_receiver: self.client.take_event_receiver() }
13224 }
13225
13226 /// Ensure that previous messages have been received server side. This is
13227 /// particularly useful after previous messages that created new tokens,
13228 /// because a token must be known to the sysmem server before sending the
13229 /// token to another participant.
13230 ///
13231 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
13232 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
13233 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
13234 /// to mitigate the possibility of a hostile/fake
13235 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
13236 /// Another way is to pass the token to
13237 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
13238 /// the token as part of exchanging it for a
13239 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
13240 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
13241 /// of stalling.
13242 ///
13243 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
13244 /// and then starting and completing a `Sync`, it's then safe to send the
13245 /// `BufferCollectionToken` client ends to other participants knowing the
13246 /// server will recognize the tokens when they're sent by the other
13247 /// participants to sysmem in a
13248 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
13249 /// efficient way to create tokens while avoiding unnecessary round trips.
13250 ///
13251 /// Other options include waiting for each
13252 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
13253 /// individually (using separate call to `Sync` after each), or calling
13254 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
13255 /// converted to a `BufferCollection` via
13256 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
13257 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
13258 /// the sync step and can create multiple tokens at once.
13259 pub fn r#sync(
13260 &self,
13261 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
13262 NodeProxyInterface::r#sync(self)
13263 }
13264
13265 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
13266 ///
13267 /// Normally a participant will convert a `BufferCollectionToken` into a
13268 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
13269 /// `Release` via the token (and then close the channel immediately or
13270 /// shortly later in response to server closing the server end), which
13271 /// avoids causing buffer collection failure. Without a prior `Release`,
13272 /// closing the `BufferCollectionToken` client end will cause buffer
13273 /// collection failure.
13274 ///
13275 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
13276 ///
13277 /// By default the server handles unexpected closure of a
13278 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
13279 /// first) by failing the buffer collection. Partly this is to expedite
13280 /// closing VMO handles to reclaim memory when any participant fails. If a
13281 /// participant would like to cleanly close a `BufferCollection` without
13282 /// causing buffer collection failure, the participant can send `Release`
13283 /// before closing the `BufferCollection` client end. The `Release` can
13284 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
13285 /// buffer collection won't require constraints from this node in order to
13286 /// allocate. If after `SetConstraints`, the constraints are retained and
13287 /// aggregated, despite the lack of `BufferCollection` connection at the
13288 /// time of constraints aggregation.
13289 ///
13290 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
13291 ///
13292 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
13293 /// end (without `Release` first) will trigger failure of the buffer
13294 /// collection. To close a `BufferCollectionTokenGroup` channel without
13295 /// failing the buffer collection, ensure that AllChildrenPresent() has been
13296 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
13297 /// client end.
13298 ///
13299 /// If `Release` occurs before
13300 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
13301 /// buffer collection will fail (triggered by reception of `Release` without
13302 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
13303 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
13304 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
13305 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
13306 /// close requires `AllChildrenPresent` (if not already sent), then
13307 /// `Release`, then close client end.
13308 ///
13309 /// If `Release` occurs after `AllChildrenPresent`, the children and all
13310 /// their constraints remain intact (just as they would if the
13311 /// `BufferCollectionTokenGroup` channel had remained open), and the client
13312 /// end close doesn't trigger buffer collection failure.
13313 ///
13314 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
13315 ///
13316 /// For brevity, the per-channel-protocol paragraphs above ignore the
13317 /// separate failure domain created by
13318 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
13319 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
13320 /// unexpectedly closes (without `Release` first) and that client end is
13321 /// under a failure domain, instead of failing the whole buffer collection,
13322 /// the failure domain is failed, but the buffer collection itself is
13323 /// isolated from failure of the failure domain. Such failure domains can be
13324 /// nested, in which case only the inner-most failure domain in which the
13325 /// `Node` resides fails.
13326 pub fn r#release(&self) -> Result<(), fidl::Error> {
13327 NodeProxyInterface::r#release(self)
13328 }
13329
13330 /// Set a name for VMOs in this buffer collection.
13331 ///
13332 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
13333 /// will be truncated to fit. The name of the vmo will be suffixed with the
13334 /// buffer index within the collection (if the suffix fits within
13335 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
13336 /// listed in the inspect data.
13337 ///
13338 /// The name only affects VMOs allocated after the name is set; this call
13339 /// does not rename existing VMOs. If multiple clients set different names
13340 /// then the larger priority value will win. Setting a new name with the
13341 /// same priority as a prior name doesn't change the name.
13342 ///
13343 /// All table fields are currently required.
13344 ///
13345 /// + request `priority` The name is only set if this is the first `SetName`
13346 /// or if `priority` is greater than any previous `priority` value in
13347 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
13348 /// + request `name` The name for VMOs created under this buffer collection.
13349 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
13350 NodeProxyInterface::r#set_name(self, payload)
13351 }
13352
13353 /// Set information about the current client that can be used by sysmem to
13354 /// help diagnose leaking memory and allocation stalls waiting for a
13355 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
13356 ///
13357 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
13358 /// `Node`(s) derived from this `Node`, unless overriden by
13359 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
13360 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
13361 ///
13362 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
13363 /// `Allocator` is the most efficient way to ensure that all
13364 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
13365 /// set, and is also more efficient than separately sending the same debug
13366 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
13367 /// created [`fuchsia.sysmem2/Node`].
13368 ///
13369 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
13370 /// indicate which client is closing their channel first, leading to subtree
13371 /// failure (which can be normal if the purpose of the subtree is over, but
13372 /// if happening earlier than expected, the client-channel-specific name can
13373 /// help diagnose where the failure is first coming from, from sysmem's
13374 /// point of view).
13375 ///
13376 /// All table fields are currently required.
13377 ///
13378 /// + request `name` This can be an arbitrary string, but the current
13379 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
13380 /// + request `id` This can be an arbitrary id, but the current process ID
13381 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
13382 pub fn r#set_debug_client_info(
13383 &self,
13384 mut payload: &NodeSetDebugClientInfoRequest,
13385 ) -> Result<(), fidl::Error> {
13386 NodeProxyInterface::r#set_debug_client_info(self, payload)
13387 }
13388
13389 /// Sysmem logs a warning if sysmem hasn't seen
13390 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
13391 /// within 5 seconds after creation of a new collection.
13392 ///
13393 /// Clients can call this method to change when the log is printed. If
13394 /// multiple client set the deadline, it's unspecified which deadline will
13395 /// take effect.
13396 ///
13397 /// In most cases the default works well.
13398 ///
13399 /// All table fields are currently required.
13400 ///
13401 /// + request `deadline` The time at which sysmem will start trying to log
13402 /// the warning, unless all constraints are with sysmem by then.
13403 pub fn r#set_debug_timeout_log_deadline(
13404 &self,
13405 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
13406 ) -> Result<(), fidl::Error> {
13407 NodeProxyInterface::r#set_debug_timeout_log_deadline(self, payload)
13408 }
13409
13410 /// This enables verbose logging for the buffer collection.
13411 ///
13412 /// Verbose logging includes constraints set via
13413 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
13414 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
13415 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
13416 /// the tree of `Node`(s).
13417 ///
13418 /// Normally sysmem prints only a single line complaint when aggregation
13419 /// fails, with just the specific detailed reason that aggregation failed,
13420 /// with little surrounding context. While this is often enough to diagnose
13421 /// a problem if only a small change was made and everything was working
13422 /// before the small change, it's often not particularly helpful for getting
13423 /// a new buffer collection to work for the first time. Especially with
13424 /// more complex trees of nodes, involving things like
13425 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
13426 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
13427 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
13428 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
13429 /// looks like and why it's failing a logical allocation, or why a tree or
13430 /// subtree is failing sooner than expected.
13431 ///
13432 /// The intent of the extra logging is to be acceptable from a performance
13433 /// point of view, under the assumption that verbose logging is only enabled
13434 /// on a low number of buffer collections. If we're not tracking down a bug,
13435 /// we shouldn't send this message.
13436 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
13437 NodeProxyInterface::r#set_verbose_logging(self)
13438 }
13439
13440 /// This gets a handle that can be used as a parameter to
13441 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
13442 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
13443 /// client obtained this handle from this `Node`.
13444 ///
13445 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
13446 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
13447 /// despite the two calls typically being on different channels.
13448 ///
13449 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
13450 ///
13451 /// All table fields are currently required.
13452 ///
13453 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
13454 /// different `Node` channel, to prove that the client obtained the handle
13455 /// from this `Node`.
13456 pub fn r#get_node_ref(
13457 &self,
13458 ) -> fidl::client::QueryResponseFut<
13459 NodeGetNodeRefResponse,
13460 fidl::encoding::DefaultFuchsiaResourceDialect,
13461 > {
13462 NodeProxyInterface::r#get_node_ref(self)
13463 }
13464
13465 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
13466 /// rooted at a different child token of a common parent
13467 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
13468 /// passed-in `node_ref`.
13469 ///
13470 /// This call is for assisting with admission control de-duplication, and
13471 /// with debugging.
13472 ///
13473 /// The `node_ref` must be obtained using
13474 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
13475 ///
13476 /// The `node_ref` can be a duplicated handle; it's not necessary to call
13477 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
13478 ///
13479 /// If a calling token may not actually be a valid token at all due to a
13480 /// potentially hostile/untrusted provider of the token, call
13481 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
13482 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
13483 /// never responds due to a calling token not being a real token (not really
13484 /// talking to sysmem). Another option is to call
13485 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
13486 /// which also validates the token along with converting it to a
13487 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
13488 ///
13489 /// All table fields are currently required.
13490 ///
13491 /// - response `is_alternate`
13492 /// - true: The first parent node in common between the calling node and
13493 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
13494 /// that the calling `Node` and the `node_ref` `Node` will not have both
13495 /// their constraints apply - rather sysmem will choose one or the other
13496 /// of the constraints - never both. This is because only one child of
13497 /// a `BufferCollectionTokenGroup` is selected during logical
13498 /// allocation, with only that one child's subtree contributing to
13499 /// constraints aggregation.
13500 /// - false: The first parent node in common between the calling `Node`
13501 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
13502 /// Currently, this means the first parent node in common is a
13503 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
13504 /// `Release`ed). This means that the calling `Node` and the `node_ref`
13505 /// `Node` may have both their constraints apply during constraints
13506 /// aggregation of the logical allocation, if both `Node`(s) are
13507 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
13508 /// this case, there is no `BufferCollectionTokenGroup` that will
13509 /// directly prevent the two `Node`(s) from both being selected and
13510 /// their constraints both aggregated, but even when false, one or both
13511 /// `Node`(s) may still be eliminated from consideration if one or both
13512 /// `Node`(s) has a direct or indirect parent
13513 /// `BufferCollectionTokenGroup` which selects a child subtree other
13514 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
13515 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
13516 /// associated with the same buffer collection as the calling `Node`.
13517 /// Another reason for this error is if the `node_ref` is an
13518 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
13519 /// a real `node_ref` obtained from `GetNodeRef`.
13520 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
13521 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
13522 /// the needed rights expected on a real `node_ref`.
13523 /// * No other failing status codes are returned by this call. However,
13524 /// sysmem may add additional codes in future, so the client should have
13525 /// sensible default handling for any failing status code.
13526 pub fn r#is_alternate_for(
13527 &self,
13528 mut payload: NodeIsAlternateForRequest,
13529 ) -> fidl::client::QueryResponseFut<
13530 NodeIsAlternateForResult,
13531 fidl::encoding::DefaultFuchsiaResourceDialect,
13532 > {
13533 NodeProxyInterface::r#is_alternate_for(self, payload)
13534 }
13535
13536 /// Get the buffer collection ID. This ID is also available from
13537 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
13538 /// within the collection).
13539 ///
13540 /// This call is mainly useful in situations where we can't convey a
13541 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
13542 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
13543 /// handle, which can be joined back up with a `BufferCollection` client end
13544 /// that was created via a different path. Prefer to convey a
13545 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
13546 ///
13547 /// Trusting a `buffer_collection_id` value from a source other than sysmem
13548 /// is analogous to trusting a koid value from a source other than zircon.
13549 /// Both should be avoided unless really necessary, and both require
13550 /// caution. In some situations it may be reasonable to refer to a
13551 /// pre-established `BufferCollection` by `buffer_collection_id` via a
13552 /// protocol for efficiency reasons, but an incoming value purporting to be
13553 /// a `buffer_collection_id` is not sufficient alone to justify granting the
13554 /// sender of the `buffer_collection_id` any capability. The sender must
13555 /// first prove to a receiver that the sender has/had a VMO or has/had a
13556 /// `BufferCollectionToken` to the same collection by sending a handle that
13557 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
13558 /// `buffer_collection_id` value. The receiver should take care to avoid
13559 /// assuming that a sender had a `BufferCollectionToken` in cases where the
13560 /// sender has only proven that the sender had a VMO.
13561 ///
13562 /// - response `buffer_collection_id` This ID is unique per buffer
13563 /// collection per boot. Each buffer is uniquely identified by the
13564 /// `buffer_collection_id` and `buffer_index` together.
13565 pub fn r#get_buffer_collection_id(
13566 &self,
13567 ) -> fidl::client::QueryResponseFut<
13568 NodeGetBufferCollectionIdResponse,
13569 fidl::encoding::DefaultFuchsiaResourceDialect,
13570 > {
13571 NodeProxyInterface::r#get_buffer_collection_id(self)
13572 }
13573
13574 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
13575 /// created after this message to weak, which means that a client's `Node`
13576 /// client end (or a child created after this message) is not alone
13577 /// sufficient to keep allocated VMOs alive.
13578 ///
13579 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
13580 /// `close_weak_asap`.
13581 ///
13582 /// This message is only permitted before the `Node` becomes ready for
13583 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
13584 /// * `BufferCollectionToken`: any time
13585 /// * `BufferCollection`: before `SetConstraints`
13586 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
13587 ///
13588 /// Currently, no conversion from strong `Node` to weak `Node` after ready
13589 /// for allocation is provided, but a client can simulate that by creating
13590 /// an additional `Node` before allocation and setting that additional
13591 /// `Node` to weak, and then potentially at some point later sending
13592 /// `Release` and closing the client end of the client's strong `Node`, but
13593 /// keeping the client's weak `Node`.
13594 ///
13595 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
13596 /// collection failure (all `Node` client end(s) will see
13597 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
13598 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
13599 /// this situation until all `Node`(s) are ready for allocation. For initial
13600 /// allocation to succeed, at least one strong `Node` is required to exist
13601 /// at allocation time, but after that client receives VMO handles, that
13602 /// client can `BufferCollection.Release` and close the client end without
13603 /// causing this type of failure.
13604 ///
13605 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
13606 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
13607 /// separately as appropriate.
13608 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
13609 NodeProxyInterface::r#set_weak(self)
13610 }
13611
13612 /// This indicates to sysmem that the client is prepared to pay attention to
13613 /// `close_weak_asap`.
13614 ///
13615 /// If sent, this message must be before
13616 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
13617 ///
13618 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
13619 /// send this message before `WaitForAllBuffersAllocated`, or a parent
13620 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
13621 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
13622 /// trigger buffer collection failure.
13623 ///
13624 /// This message is necessary because weak sysmem VMOs have not always been
13625 /// a thing, so older clients are not aware of the need to pay attention to
13626 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
13627 /// sysmem weak VMO handles asap. By having this message and requiring
13628 /// participants to indicate their acceptance of this aspect of the overall
13629 /// protocol, we avoid situations where an older client is delivered a weak
13630 /// VMO without any way for sysmem to get that VMO to close quickly later
13631 /// (and on a per-buffer basis).
13632 ///
13633 /// A participant that doesn't handle `close_weak_asap` and also doesn't
13634 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
13635 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
13636 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
13637 /// same participant has a child/delegate which does retrieve VMOs, that
13638 /// child/delegate will need to send `SetWeakOk` before
13639 /// `WaitForAllBuffersAllocated`.
13640 ///
13641 /// + request `for_child_nodes_also` If present and true, this means direct
13642 /// child nodes of this node created after this message plus all
13643 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
13644 /// those nodes. Any child node of this node that was created before this
13645 /// message is not included. This setting is "sticky" in the sense that a
13646 /// subsequent `SetWeakOk` without this bool set to true does not reset
13647 /// the server-side bool. If this creates a problem for a participant, a
13648 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
13649 /// tokens instead, as appropriate. A participant should only set
13650 /// `for_child_nodes_also` true if the participant can really promise to
13651 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
13652 /// weak VMO handles held by participants holding the corresponding child
13653 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
13654 /// which are using sysmem(1) can be weak, despite the clients of those
13655 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
13656 /// direct way to find out about `close_weak_asap`. This only applies to
13657 /// descendents of this `Node` which are using sysmem(1), not to this
13658 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
13659 /// token, which will fail allocation unless an ancestor of this `Node`
13660 /// specified `for_child_nodes_also` true.
13661 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
13662 NodeProxyInterface::r#set_weak_ok(self, payload)
13663 }
13664
13665 /// The server_end will be closed after this `Node` and any child nodes have
13666 /// have released their buffer counts, making those counts available for
13667 /// reservation by a different `Node` via
13668 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
13669 ///
13670 /// The `Node` buffer counts may not be released until the entire tree of
13671 /// `Node`(s) is closed or failed, because
13672 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
13673 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
13674 /// `Node` buffer counts remain reserved until the orphaned node is later
13675 /// cleaned up.
13676 ///
13677 /// If the `Node` exceeds a fairly large number of attached eventpair server
13678 /// ends, a log message will indicate this and the `Node` (and the
13679 /// appropriate) sub-tree will fail.
13680 ///
13681 /// The `server_end` will remain open when
13682 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
13683 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
13684 /// [`fuchsia.sysmem2/BufferCollection`].
13685 ///
13686 /// This message can also be used with a
13687 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
13688 pub fn r#attach_node_tracking(
13689 &self,
13690 mut payload: NodeAttachNodeTrackingRequest,
13691 ) -> Result<(), fidl::Error> {
13692 NodeProxyInterface::r#attach_node_tracking(self, payload)
13693 }
13694}
13695
13696impl NodeProxyInterface for NodeProxy {
13697 type SyncResponseFut =
13698 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
13699 fn r#sync(&self) -> Self::SyncResponseFut {
13700 fn _decode(
13701 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
13702 ) -> Result<(), fidl::Error> {
13703 let _response = fidl::client::decode_transaction_body::<
13704 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
13705 fidl::encoding::DefaultFuchsiaResourceDialect,
13706 0x11ac2555cf575b54,
13707 >(_buf?)?
13708 .into_result::<NodeMarker>("sync")?;
13709 Ok(_response)
13710 }
13711 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
13712 (),
13713 0x11ac2555cf575b54,
13714 fidl::encoding::DynamicFlags::FLEXIBLE,
13715 _decode,
13716 )
13717 }
13718
13719 fn r#release(&self) -> Result<(), fidl::Error> {
13720 self.client.send::<fidl::encoding::EmptyPayload>(
13721 (),
13722 0x6a5cae7d6d6e04c6,
13723 fidl::encoding::DynamicFlags::FLEXIBLE,
13724 )
13725 }
13726
13727 fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
13728 self.client.send::<NodeSetNameRequest>(
13729 payload,
13730 0xb41f1624f48c1e9,
13731 fidl::encoding::DynamicFlags::FLEXIBLE,
13732 )
13733 }
13734
13735 fn r#set_debug_client_info(
13736 &self,
13737 mut payload: &NodeSetDebugClientInfoRequest,
13738 ) -> Result<(), fidl::Error> {
13739 self.client.send::<NodeSetDebugClientInfoRequest>(
13740 payload,
13741 0x5cde8914608d99b1,
13742 fidl::encoding::DynamicFlags::FLEXIBLE,
13743 )
13744 }
13745
13746 fn r#set_debug_timeout_log_deadline(
13747 &self,
13748 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
13749 ) -> Result<(), fidl::Error> {
13750 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
13751 payload,
13752 0x716b0af13d5c0806,
13753 fidl::encoding::DynamicFlags::FLEXIBLE,
13754 )
13755 }
13756
13757 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
13758 self.client.send::<fidl::encoding::EmptyPayload>(
13759 (),
13760 0x5209c77415b4dfad,
13761 fidl::encoding::DynamicFlags::FLEXIBLE,
13762 )
13763 }
13764
13765 type GetNodeRefResponseFut = fidl::client::QueryResponseFut<
13766 NodeGetNodeRefResponse,
13767 fidl::encoding::DefaultFuchsiaResourceDialect,
13768 >;
13769 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
13770 fn _decode(
13771 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
13772 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
13773 let _response = fidl::client::decode_transaction_body::<
13774 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
13775 fidl::encoding::DefaultFuchsiaResourceDialect,
13776 0x5b3d0e51614df053,
13777 >(_buf?)?
13778 .into_result::<NodeMarker>("get_node_ref")?;
13779 Ok(_response)
13780 }
13781 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
13782 (),
13783 0x5b3d0e51614df053,
13784 fidl::encoding::DynamicFlags::FLEXIBLE,
13785 _decode,
13786 )
13787 }
13788
13789 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
13790 NodeIsAlternateForResult,
13791 fidl::encoding::DefaultFuchsiaResourceDialect,
13792 >;
13793 fn r#is_alternate_for(
13794 &self,
13795 mut payload: NodeIsAlternateForRequest,
13796 ) -> Self::IsAlternateForResponseFut {
13797 fn _decode(
13798 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
13799 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
13800 let _response = fidl::client::decode_transaction_body::<
13801 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
13802 fidl::encoding::DefaultFuchsiaResourceDialect,
13803 0x3a58e00157e0825,
13804 >(_buf?)?
13805 .into_result::<NodeMarker>("is_alternate_for")?;
13806 Ok(_response.map(|x| x))
13807 }
13808 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
13809 &mut payload,
13810 0x3a58e00157e0825,
13811 fidl::encoding::DynamicFlags::FLEXIBLE,
13812 _decode,
13813 )
13814 }
13815
13816 type GetBufferCollectionIdResponseFut = fidl::client::QueryResponseFut<
13817 NodeGetBufferCollectionIdResponse,
13818 fidl::encoding::DefaultFuchsiaResourceDialect,
13819 >;
13820 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut {
13821 fn _decode(
13822 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
13823 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
13824 let _response = fidl::client::decode_transaction_body::<
13825 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
13826 fidl::encoding::DefaultFuchsiaResourceDialect,
13827 0x77d19a494b78ba8c,
13828 >(_buf?)?
13829 .into_result::<NodeMarker>("get_buffer_collection_id")?;
13830 Ok(_response)
13831 }
13832 self.client.send_query_and_decode::<
13833 fidl::encoding::EmptyPayload,
13834 NodeGetBufferCollectionIdResponse,
13835 >(
13836 (),
13837 0x77d19a494b78ba8c,
13838 fidl::encoding::DynamicFlags::FLEXIBLE,
13839 _decode,
13840 )
13841 }
13842
13843 fn r#set_weak(&self) -> Result<(), fidl::Error> {
13844 self.client.send::<fidl::encoding::EmptyPayload>(
13845 (),
13846 0x22dd3ea514eeffe1,
13847 fidl::encoding::DynamicFlags::FLEXIBLE,
13848 )
13849 }
13850
13851 fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
13852 self.client.send::<NodeSetWeakOkRequest>(
13853 &mut payload,
13854 0x38a44fc4d7724be9,
13855 fidl::encoding::DynamicFlags::FLEXIBLE,
13856 )
13857 }
13858
13859 fn r#attach_node_tracking(
13860 &self,
13861 mut payload: NodeAttachNodeTrackingRequest,
13862 ) -> Result<(), fidl::Error> {
13863 self.client.send::<NodeAttachNodeTrackingRequest>(
13864 &mut payload,
13865 0x3f22f2a293d3cdac,
13866 fidl::encoding::DynamicFlags::FLEXIBLE,
13867 )
13868 }
13869}
13870
13871pub struct NodeEventStream {
13872 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
13873}
13874
13875impl std::marker::Unpin for NodeEventStream {}
13876
13877impl futures::stream::FusedStream for NodeEventStream {
13878 fn is_terminated(&self) -> bool {
13879 self.event_receiver.is_terminated()
13880 }
13881}
13882
13883impl futures::Stream for NodeEventStream {
13884 type Item = Result<NodeEvent, fidl::Error>;
13885
13886 fn poll_next(
13887 mut self: std::pin::Pin<&mut Self>,
13888 cx: &mut std::task::Context<'_>,
13889 ) -> std::task::Poll<Option<Self::Item>> {
13890 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
13891 &mut self.event_receiver,
13892 cx
13893 )?) {
13894 Some(buf) => std::task::Poll::Ready(Some(NodeEvent::decode(buf))),
13895 None => std::task::Poll::Ready(None),
13896 }
13897 }
13898}
13899
13900#[derive(Debug)]
13901pub enum NodeEvent {
13902 #[non_exhaustive]
13903 _UnknownEvent {
13904 /// Ordinal of the event that was sent.
13905 ordinal: u64,
13906 },
13907}
13908
13909impl NodeEvent {
13910 /// Decodes a message buffer as a [`NodeEvent`].
13911 fn decode(
13912 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
13913 ) -> Result<NodeEvent, fidl::Error> {
13914 let (bytes, _handles) = buf.split_mut();
13915 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
13916 debug_assert_eq!(tx_header.tx_id, 0);
13917 match tx_header.ordinal {
13918 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
13919 Ok(NodeEvent::_UnknownEvent { ordinal: tx_header.ordinal })
13920 }
13921 _ => Err(fidl::Error::UnknownOrdinal {
13922 ordinal: tx_header.ordinal,
13923 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
13924 }),
13925 }
13926 }
13927}
13928
13929/// A Stream of incoming requests for fuchsia.sysmem2/Node.
13930pub struct NodeRequestStream {
13931 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
13932 is_terminated: bool,
13933}
13934
13935impl std::marker::Unpin for NodeRequestStream {}
13936
13937impl futures::stream::FusedStream for NodeRequestStream {
13938 fn is_terminated(&self) -> bool {
13939 self.is_terminated
13940 }
13941}
13942
13943impl fidl::endpoints::RequestStream for NodeRequestStream {
13944 type Protocol = NodeMarker;
13945 type ControlHandle = NodeControlHandle;
13946
13947 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
13948 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
13949 }
13950
13951 fn control_handle(&self) -> Self::ControlHandle {
13952 NodeControlHandle { inner: self.inner.clone() }
13953 }
13954
13955 fn into_inner(
13956 self,
13957 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
13958 {
13959 (self.inner, self.is_terminated)
13960 }
13961
13962 fn from_inner(
13963 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
13964 is_terminated: bool,
13965 ) -> Self {
13966 Self { inner, is_terminated }
13967 }
13968}
13969
13970impl futures::Stream for NodeRequestStream {
13971 type Item = Result<NodeRequest, fidl::Error>;
13972
13973 fn poll_next(
13974 mut self: std::pin::Pin<&mut Self>,
13975 cx: &mut std::task::Context<'_>,
13976 ) -> std::task::Poll<Option<Self::Item>> {
13977 let this = &mut *self;
13978 if this.inner.check_shutdown(cx) {
13979 this.is_terminated = true;
13980 return std::task::Poll::Ready(None);
13981 }
13982 if this.is_terminated {
13983 panic!("polled NodeRequestStream after completion");
13984 }
13985 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
13986 |bytes, handles| {
13987 match this.inner.channel().read_etc(cx, bytes, handles) {
13988 std::task::Poll::Ready(Ok(())) => {}
13989 std::task::Poll::Pending => return std::task::Poll::Pending,
13990 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
13991 this.is_terminated = true;
13992 return std::task::Poll::Ready(None);
13993 }
13994 std::task::Poll::Ready(Err(e)) => {
13995 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
13996 e.into(),
13997 ))));
13998 }
13999 }
14000
14001 // A message has been received from the channel
14002 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
14003
14004 std::task::Poll::Ready(Some(match header.ordinal {
14005 0x11ac2555cf575b54 => {
14006 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
14007 let mut req = fidl::new_empty!(
14008 fidl::encoding::EmptyPayload,
14009 fidl::encoding::DefaultFuchsiaResourceDialect
14010 );
14011 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14012 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14013 Ok(NodeRequest::Sync {
14014 responder: NodeSyncResponder {
14015 control_handle: std::mem::ManuallyDrop::new(control_handle),
14016 tx_id: header.tx_id,
14017 },
14018 })
14019 }
14020 0x6a5cae7d6d6e04c6 => {
14021 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14022 let mut req = fidl::new_empty!(
14023 fidl::encoding::EmptyPayload,
14024 fidl::encoding::DefaultFuchsiaResourceDialect
14025 );
14026 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14027 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14028 Ok(NodeRequest::Release { control_handle })
14029 }
14030 0xb41f1624f48c1e9 => {
14031 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14032 let mut req = fidl::new_empty!(
14033 NodeSetNameRequest,
14034 fidl::encoding::DefaultFuchsiaResourceDialect
14035 );
14036 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
14037 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14038 Ok(NodeRequest::SetName { payload: req, control_handle })
14039 }
14040 0x5cde8914608d99b1 => {
14041 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14042 let mut req = fidl::new_empty!(
14043 NodeSetDebugClientInfoRequest,
14044 fidl::encoding::DefaultFuchsiaResourceDialect
14045 );
14046 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
14047 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14048 Ok(NodeRequest::SetDebugClientInfo { payload: req, control_handle })
14049 }
14050 0x716b0af13d5c0806 => {
14051 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14052 let mut req = fidl::new_empty!(
14053 NodeSetDebugTimeoutLogDeadlineRequest,
14054 fidl::encoding::DefaultFuchsiaResourceDialect
14055 );
14056 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
14057 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14058 Ok(NodeRequest::SetDebugTimeoutLogDeadline { payload: req, control_handle })
14059 }
14060 0x5209c77415b4dfad => {
14061 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14062 let mut req = fidl::new_empty!(
14063 fidl::encoding::EmptyPayload,
14064 fidl::encoding::DefaultFuchsiaResourceDialect
14065 );
14066 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14067 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14068 Ok(NodeRequest::SetVerboseLogging { control_handle })
14069 }
14070 0x5b3d0e51614df053 => {
14071 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
14072 let mut req = fidl::new_empty!(
14073 fidl::encoding::EmptyPayload,
14074 fidl::encoding::DefaultFuchsiaResourceDialect
14075 );
14076 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14077 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14078 Ok(NodeRequest::GetNodeRef {
14079 responder: NodeGetNodeRefResponder {
14080 control_handle: std::mem::ManuallyDrop::new(control_handle),
14081 tx_id: header.tx_id,
14082 },
14083 })
14084 }
14085 0x3a58e00157e0825 => {
14086 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
14087 let mut req = fidl::new_empty!(
14088 NodeIsAlternateForRequest,
14089 fidl::encoding::DefaultFuchsiaResourceDialect
14090 );
14091 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
14092 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14093 Ok(NodeRequest::IsAlternateFor {
14094 payload: req,
14095 responder: NodeIsAlternateForResponder {
14096 control_handle: std::mem::ManuallyDrop::new(control_handle),
14097 tx_id: header.tx_id,
14098 },
14099 })
14100 }
14101 0x77d19a494b78ba8c => {
14102 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
14103 let mut req = fidl::new_empty!(
14104 fidl::encoding::EmptyPayload,
14105 fidl::encoding::DefaultFuchsiaResourceDialect
14106 );
14107 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14108 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14109 Ok(NodeRequest::GetBufferCollectionId {
14110 responder: NodeGetBufferCollectionIdResponder {
14111 control_handle: std::mem::ManuallyDrop::new(control_handle),
14112 tx_id: header.tx_id,
14113 },
14114 })
14115 }
14116 0x22dd3ea514eeffe1 => {
14117 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14118 let mut req = fidl::new_empty!(
14119 fidl::encoding::EmptyPayload,
14120 fidl::encoding::DefaultFuchsiaResourceDialect
14121 );
14122 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14123 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14124 Ok(NodeRequest::SetWeak { control_handle })
14125 }
14126 0x38a44fc4d7724be9 => {
14127 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14128 let mut req = fidl::new_empty!(
14129 NodeSetWeakOkRequest,
14130 fidl::encoding::DefaultFuchsiaResourceDialect
14131 );
14132 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetWeakOkRequest>(&header, _body_bytes, handles, &mut req)?;
14133 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14134 Ok(NodeRequest::SetWeakOk { payload: req, control_handle })
14135 }
14136 0x3f22f2a293d3cdac => {
14137 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14138 let mut req = fidl::new_empty!(
14139 NodeAttachNodeTrackingRequest,
14140 fidl::encoding::DefaultFuchsiaResourceDialect
14141 );
14142 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeAttachNodeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
14143 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14144 Ok(NodeRequest::AttachNodeTracking { payload: req, control_handle })
14145 }
14146 _ if header.tx_id == 0
14147 && header
14148 .dynamic_flags()
14149 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
14150 {
14151 Ok(NodeRequest::_UnknownMethod {
14152 ordinal: header.ordinal,
14153 control_handle: NodeControlHandle { inner: this.inner.clone() },
14154 method_type: fidl::MethodType::OneWay,
14155 })
14156 }
14157 _ if header
14158 .dynamic_flags()
14159 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
14160 {
14161 this.inner.send_framework_err(
14162 fidl::encoding::FrameworkErr::UnknownMethod,
14163 header.tx_id,
14164 header.ordinal,
14165 header.dynamic_flags(),
14166 (bytes, handles),
14167 )?;
14168 Ok(NodeRequest::_UnknownMethod {
14169 ordinal: header.ordinal,
14170 control_handle: NodeControlHandle { inner: this.inner.clone() },
14171 method_type: fidl::MethodType::TwoWay,
14172 })
14173 }
14174 _ => Err(fidl::Error::UnknownOrdinal {
14175 ordinal: header.ordinal,
14176 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
14177 }),
14178 }))
14179 },
14180 )
14181 }
14182}
14183
14184/// This protocol is the parent protocol for all nodes in the tree established
14185/// by [`fuchsia.sysmem2/BufferCollectionToken`] creation and
14186/// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] creation, including
14187/// [`fuchsia.sysmem2/BufferCollectionToken`](s) which have since been converted
14188/// to a [`fuchsia.sysmem2/BufferCollection`] channel.
14189///
14190/// Epitaphs are not used in this protocol.
14191#[derive(Debug)]
14192pub enum NodeRequest {
14193 /// Ensure that previous messages have been received server side. This is
14194 /// particularly useful after previous messages that created new tokens,
14195 /// because a token must be known to the sysmem server before sending the
14196 /// token to another participant.
14197 ///
14198 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
14199 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
14200 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
14201 /// to mitigate the possibility of a hostile/fake
14202 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
14203 /// Another way is to pass the token to
14204 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
14205 /// the token as part of exchanging it for a
14206 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
14207 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
14208 /// of stalling.
14209 ///
14210 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
14211 /// and then starting and completing a `Sync`, it's then safe to send the
14212 /// `BufferCollectionToken` client ends to other participants knowing the
14213 /// server will recognize the tokens when they're sent by the other
14214 /// participants to sysmem in a
14215 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
14216 /// efficient way to create tokens while avoiding unnecessary round trips.
14217 ///
14218 /// Other options include waiting for each
14219 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
14220 /// individually (using separate call to `Sync` after each), or calling
14221 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
14222 /// converted to a `BufferCollection` via
14223 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
14224 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
14225 /// the sync step and can create multiple tokens at once.
14226 Sync { responder: NodeSyncResponder },
14227 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
14228 ///
14229 /// Normally a participant will convert a `BufferCollectionToken` into a
14230 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
14231 /// `Release` via the token (and then close the channel immediately or
14232 /// shortly later in response to server closing the server end), which
14233 /// avoids causing buffer collection failure. Without a prior `Release`,
14234 /// closing the `BufferCollectionToken` client end will cause buffer
14235 /// collection failure.
14236 ///
14237 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
14238 ///
14239 /// By default the server handles unexpected closure of a
14240 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
14241 /// first) by failing the buffer collection. Partly this is to expedite
14242 /// closing VMO handles to reclaim memory when any participant fails. If a
14243 /// participant would like to cleanly close a `BufferCollection` without
14244 /// causing buffer collection failure, the participant can send `Release`
14245 /// before closing the `BufferCollection` client end. The `Release` can
14246 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
14247 /// buffer collection won't require constraints from this node in order to
14248 /// allocate. If after `SetConstraints`, the constraints are retained and
14249 /// aggregated, despite the lack of `BufferCollection` connection at the
14250 /// time of constraints aggregation.
14251 ///
14252 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
14253 ///
14254 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
14255 /// end (without `Release` first) will trigger failure of the buffer
14256 /// collection. To close a `BufferCollectionTokenGroup` channel without
14257 /// failing the buffer collection, ensure that AllChildrenPresent() has been
14258 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
14259 /// client end.
14260 ///
14261 /// If `Release` occurs before
14262 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
14263 /// buffer collection will fail (triggered by reception of `Release` without
14264 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
14265 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
14266 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
14267 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
14268 /// close requires `AllChildrenPresent` (if not already sent), then
14269 /// `Release`, then close client end.
14270 ///
14271 /// If `Release` occurs after `AllChildrenPresent`, the children and all
14272 /// their constraints remain intact (just as they would if the
14273 /// `BufferCollectionTokenGroup` channel had remained open), and the client
14274 /// end close doesn't trigger buffer collection failure.
14275 ///
14276 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
14277 ///
14278 /// For brevity, the per-channel-protocol paragraphs above ignore the
14279 /// separate failure domain created by
14280 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
14281 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
14282 /// unexpectedly closes (without `Release` first) and that client end is
14283 /// under a failure domain, instead of failing the whole buffer collection,
14284 /// the failure domain is failed, but the buffer collection itself is
14285 /// isolated from failure of the failure domain. Such failure domains can be
14286 /// nested, in which case only the inner-most failure domain in which the
14287 /// `Node` resides fails.
14288 Release { control_handle: NodeControlHandle },
14289 /// Set a name for VMOs in this buffer collection.
14290 ///
14291 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
14292 /// will be truncated to fit. The name of the vmo will be suffixed with the
14293 /// buffer index within the collection (if the suffix fits within
14294 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
14295 /// listed in the inspect data.
14296 ///
14297 /// The name only affects VMOs allocated after the name is set; this call
14298 /// does not rename existing VMOs. If multiple clients set different names
14299 /// then the larger priority value will win. Setting a new name with the
14300 /// same priority as a prior name doesn't change the name.
14301 ///
14302 /// All table fields are currently required.
14303 ///
14304 /// + request `priority` The name is only set if this is the first `SetName`
14305 /// or if `priority` is greater than any previous `priority` value in
14306 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
14307 /// + request `name` The name for VMOs created under this buffer collection.
14308 SetName { payload: NodeSetNameRequest, control_handle: NodeControlHandle },
14309 /// Set information about the current client that can be used by sysmem to
14310 /// help diagnose leaking memory and allocation stalls waiting for a
14311 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
14312 ///
14313 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
14314 /// `Node`(s) derived from this `Node`, unless overriden by
14315 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
14316 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
14317 ///
14318 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
14319 /// `Allocator` is the most efficient way to ensure that all
14320 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
14321 /// set, and is also more efficient than separately sending the same debug
14322 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
14323 /// created [`fuchsia.sysmem2/Node`].
14324 ///
14325 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
14326 /// indicate which client is closing their channel first, leading to subtree
14327 /// failure (which can be normal if the purpose of the subtree is over, but
14328 /// if happening earlier than expected, the client-channel-specific name can
14329 /// help diagnose where the failure is first coming from, from sysmem's
14330 /// point of view).
14331 ///
14332 /// All table fields are currently required.
14333 ///
14334 /// + request `name` This can be an arbitrary string, but the current
14335 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
14336 /// + request `id` This can be an arbitrary id, but the current process ID
14337 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
14338 SetDebugClientInfo { payload: NodeSetDebugClientInfoRequest, control_handle: NodeControlHandle },
14339 /// Sysmem logs a warning if sysmem hasn't seen
14340 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
14341 /// within 5 seconds after creation of a new collection.
14342 ///
14343 /// Clients can call this method to change when the log is printed. If
14344 /// multiple client set the deadline, it's unspecified which deadline will
14345 /// take effect.
14346 ///
14347 /// In most cases the default works well.
14348 ///
14349 /// All table fields are currently required.
14350 ///
14351 /// + request `deadline` The time at which sysmem will start trying to log
14352 /// the warning, unless all constraints are with sysmem by then.
14353 SetDebugTimeoutLogDeadline {
14354 payload: NodeSetDebugTimeoutLogDeadlineRequest,
14355 control_handle: NodeControlHandle,
14356 },
14357 /// This enables verbose logging for the buffer collection.
14358 ///
14359 /// Verbose logging includes constraints set via
14360 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
14361 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
14362 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
14363 /// the tree of `Node`(s).
14364 ///
14365 /// Normally sysmem prints only a single line complaint when aggregation
14366 /// fails, with just the specific detailed reason that aggregation failed,
14367 /// with little surrounding context. While this is often enough to diagnose
14368 /// a problem if only a small change was made and everything was working
14369 /// before the small change, it's often not particularly helpful for getting
14370 /// a new buffer collection to work for the first time. Especially with
14371 /// more complex trees of nodes, involving things like
14372 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
14373 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
14374 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
14375 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
14376 /// looks like and why it's failing a logical allocation, or why a tree or
14377 /// subtree is failing sooner than expected.
14378 ///
14379 /// The intent of the extra logging is to be acceptable from a performance
14380 /// point of view, under the assumption that verbose logging is only enabled
14381 /// on a low number of buffer collections. If we're not tracking down a bug,
14382 /// we shouldn't send this message.
14383 SetVerboseLogging { control_handle: NodeControlHandle },
14384 /// This gets a handle that can be used as a parameter to
14385 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
14386 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
14387 /// client obtained this handle from this `Node`.
14388 ///
14389 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
14390 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
14391 /// despite the two calls typically being on different channels.
14392 ///
14393 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
14394 ///
14395 /// All table fields are currently required.
14396 ///
14397 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
14398 /// different `Node` channel, to prove that the client obtained the handle
14399 /// from this `Node`.
14400 GetNodeRef { responder: NodeGetNodeRefResponder },
14401 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
14402 /// rooted at a different child token of a common parent
14403 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
14404 /// passed-in `node_ref`.
14405 ///
14406 /// This call is for assisting with admission control de-duplication, and
14407 /// with debugging.
14408 ///
14409 /// The `node_ref` must be obtained using
14410 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
14411 ///
14412 /// The `node_ref` can be a duplicated handle; it's not necessary to call
14413 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
14414 ///
14415 /// If a calling token may not actually be a valid token at all due to a
14416 /// potentially hostile/untrusted provider of the token, call
14417 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
14418 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
14419 /// never responds due to a calling token not being a real token (not really
14420 /// talking to sysmem). Another option is to call
14421 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
14422 /// which also validates the token along with converting it to a
14423 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
14424 ///
14425 /// All table fields are currently required.
14426 ///
14427 /// - response `is_alternate`
14428 /// - true: The first parent node in common between the calling node and
14429 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
14430 /// that the calling `Node` and the `node_ref` `Node` will not have both
14431 /// their constraints apply - rather sysmem will choose one or the other
14432 /// of the constraints - never both. This is because only one child of
14433 /// a `BufferCollectionTokenGroup` is selected during logical
14434 /// allocation, with only that one child's subtree contributing to
14435 /// constraints aggregation.
14436 /// - false: The first parent node in common between the calling `Node`
14437 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
14438 /// Currently, this means the first parent node in common is a
14439 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
14440 /// `Release`ed). This means that the calling `Node` and the `node_ref`
14441 /// `Node` may have both their constraints apply during constraints
14442 /// aggregation of the logical allocation, if both `Node`(s) are
14443 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
14444 /// this case, there is no `BufferCollectionTokenGroup` that will
14445 /// directly prevent the two `Node`(s) from both being selected and
14446 /// their constraints both aggregated, but even when false, one or both
14447 /// `Node`(s) may still be eliminated from consideration if one or both
14448 /// `Node`(s) has a direct or indirect parent
14449 /// `BufferCollectionTokenGroup` which selects a child subtree other
14450 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
14451 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
14452 /// associated with the same buffer collection as the calling `Node`.
14453 /// Another reason for this error is if the `node_ref` is an
14454 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
14455 /// a real `node_ref` obtained from `GetNodeRef`.
14456 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
14457 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
14458 /// the needed rights expected on a real `node_ref`.
14459 /// * No other failing status codes are returned by this call. However,
14460 /// sysmem may add additional codes in future, so the client should have
14461 /// sensible default handling for any failing status code.
14462 IsAlternateFor { payload: NodeIsAlternateForRequest, responder: NodeIsAlternateForResponder },
14463 /// Get the buffer collection ID. This ID is also available from
14464 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
14465 /// within the collection).
14466 ///
14467 /// This call is mainly useful in situations where we can't convey a
14468 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
14469 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
14470 /// handle, which can be joined back up with a `BufferCollection` client end
14471 /// that was created via a different path. Prefer to convey a
14472 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
14473 ///
14474 /// Trusting a `buffer_collection_id` value from a source other than sysmem
14475 /// is analogous to trusting a koid value from a source other than zircon.
14476 /// Both should be avoided unless really necessary, and both require
14477 /// caution. In some situations it may be reasonable to refer to a
14478 /// pre-established `BufferCollection` by `buffer_collection_id` via a
14479 /// protocol for efficiency reasons, but an incoming value purporting to be
14480 /// a `buffer_collection_id` is not sufficient alone to justify granting the
14481 /// sender of the `buffer_collection_id` any capability. The sender must
14482 /// first prove to a receiver that the sender has/had a VMO or has/had a
14483 /// `BufferCollectionToken` to the same collection by sending a handle that
14484 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
14485 /// `buffer_collection_id` value. The receiver should take care to avoid
14486 /// assuming that a sender had a `BufferCollectionToken` in cases where the
14487 /// sender has only proven that the sender had a VMO.
14488 ///
14489 /// - response `buffer_collection_id` This ID is unique per buffer
14490 /// collection per boot. Each buffer is uniquely identified by the
14491 /// `buffer_collection_id` and `buffer_index` together.
14492 GetBufferCollectionId { responder: NodeGetBufferCollectionIdResponder },
14493 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
14494 /// created after this message to weak, which means that a client's `Node`
14495 /// client end (or a child created after this message) is not alone
14496 /// sufficient to keep allocated VMOs alive.
14497 ///
14498 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
14499 /// `close_weak_asap`.
14500 ///
14501 /// This message is only permitted before the `Node` becomes ready for
14502 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
14503 /// * `BufferCollectionToken`: any time
14504 /// * `BufferCollection`: before `SetConstraints`
14505 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
14506 ///
14507 /// Currently, no conversion from strong `Node` to weak `Node` after ready
14508 /// for allocation is provided, but a client can simulate that by creating
14509 /// an additional `Node` before allocation and setting that additional
14510 /// `Node` to weak, and then potentially at some point later sending
14511 /// `Release` and closing the client end of the client's strong `Node`, but
14512 /// keeping the client's weak `Node`.
14513 ///
14514 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
14515 /// collection failure (all `Node` client end(s) will see
14516 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
14517 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
14518 /// this situation until all `Node`(s) are ready for allocation. For initial
14519 /// allocation to succeed, at least one strong `Node` is required to exist
14520 /// at allocation time, but after that client receives VMO handles, that
14521 /// client can `BufferCollection.Release` and close the client end without
14522 /// causing this type of failure.
14523 ///
14524 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
14525 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
14526 /// separately as appropriate.
14527 SetWeak { control_handle: NodeControlHandle },
14528 /// This indicates to sysmem that the client is prepared to pay attention to
14529 /// `close_weak_asap`.
14530 ///
14531 /// If sent, this message must be before
14532 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
14533 ///
14534 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
14535 /// send this message before `WaitForAllBuffersAllocated`, or a parent
14536 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
14537 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
14538 /// trigger buffer collection failure.
14539 ///
14540 /// This message is necessary because weak sysmem VMOs have not always been
14541 /// a thing, so older clients are not aware of the need to pay attention to
14542 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
14543 /// sysmem weak VMO handles asap. By having this message and requiring
14544 /// participants to indicate their acceptance of this aspect of the overall
14545 /// protocol, we avoid situations where an older client is delivered a weak
14546 /// VMO without any way for sysmem to get that VMO to close quickly later
14547 /// (and on a per-buffer basis).
14548 ///
14549 /// A participant that doesn't handle `close_weak_asap` and also doesn't
14550 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
14551 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
14552 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
14553 /// same participant has a child/delegate which does retrieve VMOs, that
14554 /// child/delegate will need to send `SetWeakOk` before
14555 /// `WaitForAllBuffersAllocated`.
14556 ///
14557 /// + request `for_child_nodes_also` If present and true, this means direct
14558 /// child nodes of this node created after this message plus all
14559 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
14560 /// those nodes. Any child node of this node that was created before this
14561 /// message is not included. This setting is "sticky" in the sense that a
14562 /// subsequent `SetWeakOk` without this bool set to true does not reset
14563 /// the server-side bool. If this creates a problem for a participant, a
14564 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
14565 /// tokens instead, as appropriate. A participant should only set
14566 /// `for_child_nodes_also` true if the participant can really promise to
14567 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
14568 /// weak VMO handles held by participants holding the corresponding child
14569 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
14570 /// which are using sysmem(1) can be weak, despite the clients of those
14571 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
14572 /// direct way to find out about `close_weak_asap`. This only applies to
14573 /// descendents of this `Node` which are using sysmem(1), not to this
14574 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
14575 /// token, which will fail allocation unless an ancestor of this `Node`
14576 /// specified `for_child_nodes_also` true.
14577 SetWeakOk { payload: NodeSetWeakOkRequest, control_handle: NodeControlHandle },
14578 /// The server_end will be closed after this `Node` and any child nodes have
14579 /// have released their buffer counts, making those counts available for
14580 /// reservation by a different `Node` via
14581 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
14582 ///
14583 /// The `Node` buffer counts may not be released until the entire tree of
14584 /// `Node`(s) is closed or failed, because
14585 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
14586 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
14587 /// `Node` buffer counts remain reserved until the orphaned node is later
14588 /// cleaned up.
14589 ///
14590 /// If the `Node` exceeds a fairly large number of attached eventpair server
14591 /// ends, a log message will indicate this and the `Node` (and the
14592 /// appropriate) sub-tree will fail.
14593 ///
14594 /// The `server_end` will remain open when
14595 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
14596 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
14597 /// [`fuchsia.sysmem2/BufferCollection`].
14598 ///
14599 /// This message can also be used with a
14600 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
14601 AttachNodeTracking { payload: NodeAttachNodeTrackingRequest, control_handle: NodeControlHandle },
14602 /// An interaction was received which does not match any known method.
14603 #[non_exhaustive]
14604 _UnknownMethod {
14605 /// Ordinal of the method that was called.
14606 ordinal: u64,
14607 control_handle: NodeControlHandle,
14608 method_type: fidl::MethodType,
14609 },
14610}
14611
14612impl NodeRequest {
14613 #[allow(irrefutable_let_patterns)]
14614 pub fn into_sync(self) -> Option<(NodeSyncResponder)> {
14615 if let NodeRequest::Sync { responder } = self { Some((responder)) } else { None }
14616 }
14617
14618 #[allow(irrefutable_let_patterns)]
14619 pub fn into_release(self) -> Option<(NodeControlHandle)> {
14620 if let NodeRequest::Release { control_handle } = self {
14621 Some((control_handle))
14622 } else {
14623 None
14624 }
14625 }
14626
14627 #[allow(irrefutable_let_patterns)]
14628 pub fn into_set_name(self) -> Option<(NodeSetNameRequest, NodeControlHandle)> {
14629 if let NodeRequest::SetName { payload, control_handle } = self {
14630 Some((payload, control_handle))
14631 } else {
14632 None
14633 }
14634 }
14635
14636 #[allow(irrefutable_let_patterns)]
14637 pub fn into_set_debug_client_info(
14638 self,
14639 ) -> Option<(NodeSetDebugClientInfoRequest, NodeControlHandle)> {
14640 if let NodeRequest::SetDebugClientInfo { payload, control_handle } = self {
14641 Some((payload, control_handle))
14642 } else {
14643 None
14644 }
14645 }
14646
14647 #[allow(irrefutable_let_patterns)]
14648 pub fn into_set_debug_timeout_log_deadline(
14649 self,
14650 ) -> Option<(NodeSetDebugTimeoutLogDeadlineRequest, NodeControlHandle)> {
14651 if let NodeRequest::SetDebugTimeoutLogDeadline { payload, control_handle } = self {
14652 Some((payload, control_handle))
14653 } else {
14654 None
14655 }
14656 }
14657
14658 #[allow(irrefutable_let_patterns)]
14659 pub fn into_set_verbose_logging(self) -> Option<(NodeControlHandle)> {
14660 if let NodeRequest::SetVerboseLogging { control_handle } = self {
14661 Some((control_handle))
14662 } else {
14663 None
14664 }
14665 }
14666
14667 #[allow(irrefutable_let_patterns)]
14668 pub fn into_get_node_ref(self) -> Option<(NodeGetNodeRefResponder)> {
14669 if let NodeRequest::GetNodeRef { responder } = self { Some((responder)) } else { None }
14670 }
14671
14672 #[allow(irrefutable_let_patterns)]
14673 pub fn into_is_alternate_for(
14674 self,
14675 ) -> Option<(NodeIsAlternateForRequest, NodeIsAlternateForResponder)> {
14676 if let NodeRequest::IsAlternateFor { payload, responder } = self {
14677 Some((payload, responder))
14678 } else {
14679 None
14680 }
14681 }
14682
14683 #[allow(irrefutable_let_patterns)]
14684 pub fn into_get_buffer_collection_id(self) -> Option<(NodeGetBufferCollectionIdResponder)> {
14685 if let NodeRequest::GetBufferCollectionId { responder } = self {
14686 Some((responder))
14687 } else {
14688 None
14689 }
14690 }
14691
14692 #[allow(irrefutable_let_patterns)]
14693 pub fn into_set_weak(self) -> Option<(NodeControlHandle)> {
14694 if let NodeRequest::SetWeak { control_handle } = self {
14695 Some((control_handle))
14696 } else {
14697 None
14698 }
14699 }
14700
14701 #[allow(irrefutable_let_patterns)]
14702 pub fn into_set_weak_ok(self) -> Option<(NodeSetWeakOkRequest, NodeControlHandle)> {
14703 if let NodeRequest::SetWeakOk { payload, control_handle } = self {
14704 Some((payload, control_handle))
14705 } else {
14706 None
14707 }
14708 }
14709
14710 #[allow(irrefutable_let_patterns)]
14711 pub fn into_attach_node_tracking(
14712 self,
14713 ) -> Option<(NodeAttachNodeTrackingRequest, NodeControlHandle)> {
14714 if let NodeRequest::AttachNodeTracking { payload, control_handle } = self {
14715 Some((payload, control_handle))
14716 } else {
14717 None
14718 }
14719 }
14720
14721 /// Name of the method defined in FIDL
14722 pub fn method_name(&self) -> &'static str {
14723 match *self {
14724 NodeRequest::Sync { .. } => "sync",
14725 NodeRequest::Release { .. } => "release",
14726 NodeRequest::SetName { .. } => "set_name",
14727 NodeRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
14728 NodeRequest::SetDebugTimeoutLogDeadline { .. } => "set_debug_timeout_log_deadline",
14729 NodeRequest::SetVerboseLogging { .. } => "set_verbose_logging",
14730 NodeRequest::GetNodeRef { .. } => "get_node_ref",
14731 NodeRequest::IsAlternateFor { .. } => "is_alternate_for",
14732 NodeRequest::GetBufferCollectionId { .. } => "get_buffer_collection_id",
14733 NodeRequest::SetWeak { .. } => "set_weak",
14734 NodeRequest::SetWeakOk { .. } => "set_weak_ok",
14735 NodeRequest::AttachNodeTracking { .. } => "attach_node_tracking",
14736 NodeRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
14737 "unknown one-way method"
14738 }
14739 NodeRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
14740 "unknown two-way method"
14741 }
14742 }
14743 }
14744}
14745
14746#[derive(Debug, Clone)]
14747pub struct NodeControlHandle {
14748 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
14749}
14750
14751impl NodeControlHandle {
14752 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
14753 self.inner.shutdown_with_epitaph(status.into())
14754 }
14755}
14756
14757impl fidl::endpoints::ControlHandle for NodeControlHandle {
14758 fn shutdown(&self) {
14759 self.inner.shutdown()
14760 }
14761
14762 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
14763 self.inner.shutdown_with_epitaph(status)
14764 }
14765
14766 fn is_closed(&self) -> bool {
14767 self.inner.channel().is_closed()
14768 }
14769 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
14770 self.inner.channel().on_closed()
14771 }
14772
14773 #[cfg(target_os = "fuchsia")]
14774 fn signal_peer(
14775 &self,
14776 clear_mask: zx::Signals,
14777 set_mask: zx::Signals,
14778 ) -> Result<(), zx_status::Status> {
14779 use fidl::Peered;
14780 self.inner.channel().signal_peer(clear_mask, set_mask)
14781 }
14782}
14783
14784impl NodeControlHandle {}
14785
14786#[must_use = "FIDL methods require a response to be sent"]
14787#[derive(Debug)]
14788pub struct NodeSyncResponder {
14789 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
14790 tx_id: u32,
14791}
14792
14793/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
14794/// if the responder is dropped without sending a response, so that the client
14795/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
14796impl std::ops::Drop for NodeSyncResponder {
14797 fn drop(&mut self) {
14798 self.control_handle.shutdown();
14799 // Safety: drops once, never accessed again
14800 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14801 }
14802}
14803
14804impl fidl::endpoints::Responder for NodeSyncResponder {
14805 type ControlHandle = NodeControlHandle;
14806
14807 fn control_handle(&self) -> &NodeControlHandle {
14808 &self.control_handle
14809 }
14810
14811 fn drop_without_shutdown(mut self) {
14812 // Safety: drops once, never accessed again due to mem::forget
14813 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14814 // Prevent Drop from running (which would shut down the channel)
14815 std::mem::forget(self);
14816 }
14817}
14818
14819impl NodeSyncResponder {
14820 /// Sends a response to the FIDL transaction.
14821 ///
14822 /// Sets the channel to shutdown if an error occurs.
14823 pub fn send(self) -> Result<(), fidl::Error> {
14824 let _result = self.send_raw();
14825 if _result.is_err() {
14826 self.control_handle.shutdown();
14827 }
14828 self.drop_without_shutdown();
14829 _result
14830 }
14831
14832 /// Similar to "send" but does not shutdown the channel if an error occurs.
14833 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
14834 let _result = self.send_raw();
14835 self.drop_without_shutdown();
14836 _result
14837 }
14838
14839 fn send_raw(&self) -> Result<(), fidl::Error> {
14840 self.control_handle.inner.send::<fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>>(
14841 fidl::encoding::Flexible::new(()),
14842 self.tx_id,
14843 0x11ac2555cf575b54,
14844 fidl::encoding::DynamicFlags::FLEXIBLE,
14845 )
14846 }
14847}
14848
14849#[must_use = "FIDL methods require a response to be sent"]
14850#[derive(Debug)]
14851pub struct NodeGetNodeRefResponder {
14852 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
14853 tx_id: u32,
14854}
14855
14856/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
14857/// if the responder is dropped without sending a response, so that the client
14858/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
14859impl std::ops::Drop for NodeGetNodeRefResponder {
14860 fn drop(&mut self) {
14861 self.control_handle.shutdown();
14862 // Safety: drops once, never accessed again
14863 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14864 }
14865}
14866
14867impl fidl::endpoints::Responder for NodeGetNodeRefResponder {
14868 type ControlHandle = NodeControlHandle;
14869
14870 fn control_handle(&self) -> &NodeControlHandle {
14871 &self.control_handle
14872 }
14873
14874 fn drop_without_shutdown(mut self) {
14875 // Safety: drops once, never accessed again due to mem::forget
14876 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14877 // Prevent Drop from running (which would shut down the channel)
14878 std::mem::forget(self);
14879 }
14880}
14881
14882impl NodeGetNodeRefResponder {
14883 /// Sends a response to the FIDL transaction.
14884 ///
14885 /// Sets the channel to shutdown if an error occurs.
14886 pub fn send(self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
14887 let _result = self.send_raw(payload);
14888 if _result.is_err() {
14889 self.control_handle.shutdown();
14890 }
14891 self.drop_without_shutdown();
14892 _result
14893 }
14894
14895 /// Similar to "send" but does not shutdown the channel if an error occurs.
14896 pub fn send_no_shutdown_on_err(
14897 self,
14898 mut payload: NodeGetNodeRefResponse,
14899 ) -> Result<(), fidl::Error> {
14900 let _result = self.send_raw(payload);
14901 self.drop_without_shutdown();
14902 _result
14903 }
14904
14905 fn send_raw(&self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
14906 self.control_handle.inner.send::<fidl::encoding::FlexibleType<NodeGetNodeRefResponse>>(
14907 fidl::encoding::Flexible::new(&mut payload),
14908 self.tx_id,
14909 0x5b3d0e51614df053,
14910 fidl::encoding::DynamicFlags::FLEXIBLE,
14911 )
14912 }
14913}
14914
14915#[must_use = "FIDL methods require a response to be sent"]
14916#[derive(Debug)]
14917pub struct NodeIsAlternateForResponder {
14918 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
14919 tx_id: u32,
14920}
14921
14922/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
14923/// if the responder is dropped without sending a response, so that the client
14924/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
14925impl std::ops::Drop for NodeIsAlternateForResponder {
14926 fn drop(&mut self) {
14927 self.control_handle.shutdown();
14928 // Safety: drops once, never accessed again
14929 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14930 }
14931}
14932
14933impl fidl::endpoints::Responder for NodeIsAlternateForResponder {
14934 type ControlHandle = NodeControlHandle;
14935
14936 fn control_handle(&self) -> &NodeControlHandle {
14937 &self.control_handle
14938 }
14939
14940 fn drop_without_shutdown(mut self) {
14941 // Safety: drops once, never accessed again due to mem::forget
14942 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14943 // Prevent Drop from running (which would shut down the channel)
14944 std::mem::forget(self);
14945 }
14946}
14947
14948impl NodeIsAlternateForResponder {
14949 /// Sends a response to the FIDL transaction.
14950 ///
14951 /// Sets the channel to shutdown if an error occurs.
14952 pub fn send(
14953 self,
14954 mut result: Result<&NodeIsAlternateForResponse, Error>,
14955 ) -> Result<(), fidl::Error> {
14956 let _result = self.send_raw(result);
14957 if _result.is_err() {
14958 self.control_handle.shutdown();
14959 }
14960 self.drop_without_shutdown();
14961 _result
14962 }
14963
14964 /// Similar to "send" but does not shutdown the channel if an error occurs.
14965 pub fn send_no_shutdown_on_err(
14966 self,
14967 mut result: Result<&NodeIsAlternateForResponse, Error>,
14968 ) -> Result<(), fidl::Error> {
14969 let _result = self.send_raw(result);
14970 self.drop_without_shutdown();
14971 _result
14972 }
14973
14974 fn send_raw(
14975 &self,
14976 mut result: Result<&NodeIsAlternateForResponse, Error>,
14977 ) -> Result<(), fidl::Error> {
14978 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
14979 NodeIsAlternateForResponse,
14980 Error,
14981 >>(
14982 fidl::encoding::FlexibleResult::new(result),
14983 self.tx_id,
14984 0x3a58e00157e0825,
14985 fidl::encoding::DynamicFlags::FLEXIBLE,
14986 )
14987 }
14988}
14989
14990#[must_use = "FIDL methods require a response to be sent"]
14991#[derive(Debug)]
14992pub struct NodeGetBufferCollectionIdResponder {
14993 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
14994 tx_id: u32,
14995}
14996
14997/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
14998/// if the responder is dropped without sending a response, so that the client
14999/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
15000impl std::ops::Drop for NodeGetBufferCollectionIdResponder {
15001 fn drop(&mut self) {
15002 self.control_handle.shutdown();
15003 // Safety: drops once, never accessed again
15004 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
15005 }
15006}
15007
15008impl fidl::endpoints::Responder for NodeGetBufferCollectionIdResponder {
15009 type ControlHandle = NodeControlHandle;
15010
15011 fn control_handle(&self) -> &NodeControlHandle {
15012 &self.control_handle
15013 }
15014
15015 fn drop_without_shutdown(mut self) {
15016 // Safety: drops once, never accessed again due to mem::forget
15017 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
15018 // Prevent Drop from running (which would shut down the channel)
15019 std::mem::forget(self);
15020 }
15021}
15022
15023impl NodeGetBufferCollectionIdResponder {
15024 /// Sends a response to the FIDL transaction.
15025 ///
15026 /// Sets the channel to shutdown if an error occurs.
15027 pub fn send(self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
15028 let _result = self.send_raw(payload);
15029 if _result.is_err() {
15030 self.control_handle.shutdown();
15031 }
15032 self.drop_without_shutdown();
15033 _result
15034 }
15035
15036 /// Similar to "send" but does not shutdown the channel if an error occurs.
15037 pub fn send_no_shutdown_on_err(
15038 self,
15039 mut payload: &NodeGetBufferCollectionIdResponse,
15040 ) -> Result<(), fidl::Error> {
15041 let _result = self.send_raw(payload);
15042 self.drop_without_shutdown();
15043 _result
15044 }
15045
15046 fn send_raw(&self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
15047 self.control_handle
15048 .inner
15049 .send::<fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>>(
15050 fidl::encoding::Flexible::new(payload),
15051 self.tx_id,
15052 0x77d19a494b78ba8c,
15053 fidl::encoding::DynamicFlags::FLEXIBLE,
15054 )
15055 }
15056}
15057
15058#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
15059pub struct SecureMemMarker;
15060
15061impl fidl::endpoints::ProtocolMarker for SecureMemMarker {
15062 type Proxy = SecureMemProxy;
15063 type RequestStream = SecureMemRequestStream;
15064 #[cfg(target_os = "fuchsia")]
15065 type SynchronousProxy = SecureMemSynchronousProxy;
15066
15067 const DEBUG_NAME: &'static str = "(anonymous) SecureMem";
15068}
15069pub type SecureMemGetPhysicalSecureHeapsResult =
15070 Result<SecureMemGetPhysicalSecureHeapsResponse, Error>;
15071pub type SecureMemGetDynamicSecureHeapsResult =
15072 Result<SecureMemGetDynamicSecureHeapsResponse, Error>;
15073pub type SecureMemGetPhysicalSecureHeapPropertiesResult =
15074 Result<SecureMemGetPhysicalSecureHeapPropertiesResponse, Error>;
15075pub type SecureMemAddSecureHeapPhysicalRangeResult = Result<(), Error>;
15076pub type SecureMemDeleteSecureHeapPhysicalRangeResult = Result<(), Error>;
15077pub type SecureMemModifySecureHeapPhysicalRangeResult = Result<(), Error>;
15078pub type SecureMemZeroSubRangeResult = Result<(), Error>;
15079
15080pub trait SecureMemProxyInterface: Send + Sync {
15081 type GetPhysicalSecureHeapsResponseFut: std::future::Future<Output = Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error>>
15082 + Send;
15083 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut;
15084 type GetDynamicSecureHeapsResponseFut: std::future::Future<Output = Result<SecureMemGetDynamicSecureHeapsResult, fidl::Error>>
15085 + Send;
15086 fn r#get_dynamic_secure_heaps(&self) -> Self::GetDynamicSecureHeapsResponseFut;
15087 type GetPhysicalSecureHeapPropertiesResponseFut: std::future::Future<
15088 Output = Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error>,
15089 > + Send;
15090 fn r#get_physical_secure_heap_properties(
15091 &self,
15092 payload: &SecureMemGetPhysicalSecureHeapPropertiesRequest,
15093 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut;
15094 type AddSecureHeapPhysicalRangeResponseFut: std::future::Future<Output = Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error>>
15095 + Send;
15096 fn r#add_secure_heap_physical_range(
15097 &self,
15098 payload: &SecureMemAddSecureHeapPhysicalRangeRequest,
15099 ) -> Self::AddSecureHeapPhysicalRangeResponseFut;
15100 type DeleteSecureHeapPhysicalRangeResponseFut: std::future::Future<
15101 Output = Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error>,
15102 > + Send;
15103 fn r#delete_secure_heap_physical_range(
15104 &self,
15105 payload: &SecureMemDeleteSecureHeapPhysicalRangeRequest,
15106 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut;
15107 type ModifySecureHeapPhysicalRangeResponseFut: std::future::Future<
15108 Output = Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error>,
15109 > + Send;
15110 fn r#modify_secure_heap_physical_range(
15111 &self,
15112 payload: &SecureMemModifySecureHeapPhysicalRangeRequest,
15113 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut;
15114 type ZeroSubRangeResponseFut: std::future::Future<Output = Result<SecureMemZeroSubRangeResult, fidl::Error>>
15115 + Send;
15116 fn r#zero_sub_range(
15117 &self,
15118 payload: &SecureMemZeroSubRangeRequest,
15119 ) -> Self::ZeroSubRangeResponseFut;
15120}
15121#[derive(Debug)]
15122#[cfg(target_os = "fuchsia")]
15123pub struct SecureMemSynchronousProxy {
15124 client: fidl::client::sync::Client,
15125}
15126
15127#[cfg(target_os = "fuchsia")]
15128impl fidl::endpoints::SynchronousProxy for SecureMemSynchronousProxy {
15129 type Proxy = SecureMemProxy;
15130 type Protocol = SecureMemMarker;
15131
15132 fn from_channel(inner: fidl::Channel) -> Self {
15133 Self::new(inner)
15134 }
15135
15136 fn into_channel(self) -> fidl::Channel {
15137 self.client.into_channel()
15138 }
15139
15140 fn as_channel(&self) -> &fidl::Channel {
15141 self.client.as_channel()
15142 }
15143}
15144
15145#[cfg(target_os = "fuchsia")]
15146impl SecureMemSynchronousProxy {
15147 pub fn new(channel: fidl::Channel) -> Self {
15148 Self { client: fidl::client::sync::Client::new(channel) }
15149 }
15150
15151 pub fn into_channel(self) -> fidl::Channel {
15152 self.client.into_channel()
15153 }
15154
15155 /// Waits until an event arrives and returns it. It is safe for other
15156 /// threads to make concurrent requests while waiting for an event.
15157 pub fn wait_for_event(
15158 &self,
15159 deadline: zx::MonotonicInstant,
15160 ) -> Result<SecureMemEvent, fidl::Error> {
15161 SecureMemEvent::decode(self.client.wait_for_event::<SecureMemMarker>(deadline)?)
15162 }
15163
15164 /// Gets the physical address and length of any secure heap whose physical
15165 /// range is configured via the TEE.
15166 ///
15167 /// Presently, these will be fixed physical addresses and lengths, with the
15168 /// location plumbed via the TEE.
15169 ///
15170 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
15171 /// when there isn't any special heap-specific per-VMO setup or teardown
15172 /// required.
15173 ///
15174 /// The physical range must be secured/protected by the TEE before the
15175 /// securemem driver responds to this request with success.
15176 ///
15177 /// Sysmem should only call this once. Returning zero heaps is not a
15178 /// failure.
15179 ///
15180 /// Errors:
15181 /// * PROTOCOL_DEVIATION - called more than once.
15182 /// * UNSPECIFIED - generic internal error (such as in communication
15183 /// with TEE which doesn't generate zx_status_t errors).
15184 /// * other errors are allowed; any other errors should be treated the same
15185 /// as UNSPECIFIED.
15186 pub fn r#get_physical_secure_heaps(
15187 &self,
15188 ___deadline: zx::MonotonicInstant,
15189 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
15190 let _response = self.client.send_query::<
15191 fidl::encoding::EmptyPayload,
15192 fidl::encoding::FlexibleResultType<SecureMemGetPhysicalSecureHeapsResponse, Error>,
15193 SecureMemMarker,
15194 >(
15195 (),
15196 0x38716300592073e3,
15197 fidl::encoding::DynamicFlags::FLEXIBLE,
15198 ___deadline,
15199 )?
15200 .into_result::<SecureMemMarker>("get_physical_secure_heaps")?;
15201 Ok(_response.map(|x| x))
15202 }
15203
15204 /// Gets information about any secure heaps whose physical pages are not
15205 /// configured by the TEE, but by sysmem.
15206 ///
15207 /// Sysmem should only call this once. Returning zero heaps is not a
15208 /// failure.
15209 ///
15210 /// Errors:
15211 /// * PROTOCOL_DEVIATION - called more than once.
15212 /// * UNSPECIFIED - generic internal error (such as in communication
15213 /// with TEE which doesn't generate zx_status_t errors).
15214 /// * other errors are allowed; any other errors should be treated the same
15215 /// as UNSPECIFIED.
15216 pub fn r#get_dynamic_secure_heaps(
15217 &self,
15218 ___deadline: zx::MonotonicInstant,
15219 ) -> Result<SecureMemGetDynamicSecureHeapsResult, fidl::Error> {
15220 let _response = self.client.send_query::<
15221 fidl::encoding::EmptyPayload,
15222 fidl::encoding::FlexibleResultType<SecureMemGetDynamicSecureHeapsResponse, Error>,
15223 SecureMemMarker,
15224 >(
15225 (),
15226 0x1190847f99952834,
15227 fidl::encoding::DynamicFlags::FLEXIBLE,
15228 ___deadline,
15229 )?
15230 .into_result::<SecureMemMarker>("get_dynamic_secure_heaps")?;
15231 Ok(_response.map(|x| x))
15232 }
15233
15234 /// This request from sysmem to the securemem driver gets the properties of
15235 /// a protected/secure heap.
15236 ///
15237 /// This only handles heaps with a single contiguous physical extent.
15238 ///
15239 /// The heap's entire physical range is indicated in case this request needs
15240 /// some physical space to auto-detect how many ranges are REE-usable. Any
15241 /// temporary HW protection ranges will be deleted before this request
15242 /// completes.
15243 ///
15244 /// Errors:
15245 /// * UNSPECIFIED - generic internal error (such as in communication
15246 /// with TEE which doesn't generate zx_status_t errors).
15247 /// * other errors are allowed; any other errors should be treated the same
15248 /// as UNSPECIFIED.
15249 pub fn r#get_physical_secure_heap_properties(
15250 &self,
15251 mut payload: &SecureMemGetPhysicalSecureHeapPropertiesRequest,
15252 ___deadline: zx::MonotonicInstant,
15253 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
15254 let _response = self.client.send_query::<
15255 SecureMemGetPhysicalSecureHeapPropertiesRequest,
15256 fidl::encoding::FlexibleResultType<SecureMemGetPhysicalSecureHeapPropertiesResponse, Error>,
15257 SecureMemMarker,
15258 >(
15259 payload,
15260 0xc6f06889009c7bc,
15261 fidl::encoding::DynamicFlags::FLEXIBLE,
15262 ___deadline,
15263 )?
15264 .into_result::<SecureMemMarker>("get_physical_secure_heap_properties")?;
15265 Ok(_response.map(|x| x))
15266 }
15267
15268 /// This request from sysmem to the securemem driver conveys a physical
15269 /// range to add, for a heap whose physical range(s) are set up via
15270 /// sysmem.
15271 ///
15272 /// Only sysmem can call this because only sysmem is handed the client end
15273 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15274 /// securemem driver is the server end of this protocol.
15275 ///
15276 /// The securemem driver must configure all the covered offsets as protected
15277 /// before responding to this message with success.
15278 ///
15279 /// On failure, the securemem driver must ensure the protected range was not
15280 /// created.
15281 ///
15282 /// Sysmem must only call this up to once if dynamic_protection_ranges
15283 /// false.
15284 ///
15285 /// If dynamic_protection_ranges is true, sysmem can call this multiple
15286 /// times as long as the current number of ranges never exceeds
15287 /// max_protected_range_count.
15288 ///
15289 /// The caller must not attempt to add a range that matches an
15290 /// already-existing range. Added ranges can overlap each other as long as
15291 /// no two ranges match exactly.
15292 ///
15293 /// Errors:
15294 /// * PROTOCOL_DEVIATION - called more than once when
15295 /// !dynamic_protection_ranges. Adding a heap that would cause overall
15296 /// heap count to exceed max_protected_range_count. Unexpected heap, or
15297 /// range that doesn't conform to protected_range_granularity. See log.
15298 /// * UNSPECIFIED - generic internal error (such as in communication
15299 /// with TEE which doesn't generate zx_status_t errors).
15300 /// * other errors are possible, such as from communication failures or
15301 /// server propagation of failures.
15302 pub fn r#add_secure_heap_physical_range(
15303 &self,
15304 mut payload: &SecureMemAddSecureHeapPhysicalRangeRequest,
15305 ___deadline: zx::MonotonicInstant,
15306 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
15307 let _response = self.client.send_query::<
15308 SecureMemAddSecureHeapPhysicalRangeRequest,
15309 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15310 SecureMemMarker,
15311 >(
15312 payload,
15313 0x35f695b9b6c7217a,
15314 fidl::encoding::DynamicFlags::FLEXIBLE,
15315 ___deadline,
15316 )?
15317 .into_result::<SecureMemMarker>("add_secure_heap_physical_range")?;
15318 Ok(_response.map(|x| x))
15319 }
15320
15321 /// This request from sysmem to the securemem driver conveys a physical
15322 /// range to delete, for a heap whose physical range(s) are set up via
15323 /// sysmem.
15324 ///
15325 /// Only sysmem can call this because only sysmem is handed the client end
15326 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15327 /// securemem driver is the server end of this protocol.
15328 ///
15329 /// The securemem driver must configure all the covered offsets as not
15330 /// protected before responding to this message with success.
15331 ///
15332 /// On failure, the securemem driver must ensure the protected range was not
15333 /// deleted.
15334 ///
15335 /// Sysmem must not call this if dynamic_protection_ranges false.
15336 ///
15337 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
15338 /// on various ranges that exist at the time of the call.
15339 ///
15340 /// If any portion of the range being deleted is not also covered by another
15341 /// protected range, then any ongoing DMA to any part of the entire range
15342 /// may be interrupted / may fail, potentially in a way that's disruptive to
15343 /// the entire system (bus lockup or similar, depending on device details).
15344 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
15345 /// any portion of the range being deleted, unless the caller has other
15346 /// active ranges covering every block of the range being deleted. Ongoing
15347 /// DMA to/from blocks outside the range being deleted is never impacted by
15348 /// the deletion.
15349 ///
15350 /// Errors:
15351 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15352 /// Unexpected heap, or range that doesn't conform to
15353 /// protected_range_granularity.
15354 /// * UNSPECIFIED - generic internal error (such as in communication
15355 /// with TEE which doesn't generate zx_status_t errors).
15356 /// * NOT_FOUND - the specified range is not found.
15357 /// * other errors are possible, such as from communication failures or
15358 /// server propagation of failures.
15359 pub fn r#delete_secure_heap_physical_range(
15360 &self,
15361 mut payload: &SecureMemDeleteSecureHeapPhysicalRangeRequest,
15362 ___deadline: zx::MonotonicInstant,
15363 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
15364 let _response = self.client.send_query::<
15365 SecureMemDeleteSecureHeapPhysicalRangeRequest,
15366 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15367 SecureMemMarker,
15368 >(
15369 payload,
15370 0xeaa58c650264c9e,
15371 fidl::encoding::DynamicFlags::FLEXIBLE,
15372 ___deadline,
15373 )?
15374 .into_result::<SecureMemMarker>("delete_secure_heap_physical_range")?;
15375 Ok(_response.map(|x| x))
15376 }
15377
15378 /// This request from sysmem to the securemem driver conveys a physical
15379 /// range to modify and its new base and length, for a heap whose physical
15380 /// range(s) are set up via sysmem.
15381 ///
15382 /// Only sysmem can call this because only sysmem is handed the client end
15383 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15384 /// securemem driver is the server end of this protocol.
15385 ///
15386 /// The securemem driver must configure the range to cover only the new
15387 /// offsets before responding to this message with success.
15388 ///
15389 /// On failure, the securemem driver must ensure the range was not changed.
15390 ///
15391 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
15392 /// must not call this if !is_mod_protected_range_available.
15393 ///
15394 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
15395 /// on various ranges that exist at the time of the call.
15396 ///
15397 /// The range must only be modified at one end or the other, but not both.
15398 /// If the range is getting shorter, and the un-covered blocks are not
15399 /// covered by other active ranges, any ongoing DMA to the entire range
15400 /// that's geting shorter may fail in a way that disrupts the entire system
15401 /// (bus lockup or similar), so the caller must ensure that no DMA is
15402 /// ongoing to any portion of a range that is getting shorter, unless the
15403 /// blocks being un-covered by the modification to this range are all
15404 /// covered by other active ranges, in which case no disruption to ongoing
15405 /// DMA will occur.
15406 ///
15407 /// If a range is modified to become <= zero length, the range is deleted.
15408 ///
15409 /// Errors:
15410 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15411 /// Unexpected heap, or old_range or new_range that doesn't conform to
15412 /// protected_range_granularity, or old_range and new_range differ in
15413 /// both begin and end (disallowed).
15414 /// * UNSPECIFIED - generic internal error (such as in communication
15415 /// with TEE which doesn't generate zx_status_t errors).
15416 /// * NOT_FOUND - the specified range is not found.
15417 /// * other errors are possible, such as from communication failures or
15418 /// server propagation of failures.
15419 pub fn r#modify_secure_heap_physical_range(
15420 &self,
15421 mut payload: &SecureMemModifySecureHeapPhysicalRangeRequest,
15422 ___deadline: zx::MonotonicInstant,
15423 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
15424 let _response = self.client.send_query::<
15425 SecureMemModifySecureHeapPhysicalRangeRequest,
15426 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15427 SecureMemMarker,
15428 >(
15429 payload,
15430 0x60b7448aa1187734,
15431 fidl::encoding::DynamicFlags::FLEXIBLE,
15432 ___deadline,
15433 )?
15434 .into_result::<SecureMemMarker>("modify_secure_heap_physical_range")?;
15435 Ok(_response.map(|x| x))
15436 }
15437
15438 /// Zero a sub-range of a currently-existing physical range added via
15439 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
15440 /// exactly one physical range, and must not overlap with any other
15441 /// physical range.
15442 ///
15443 /// is_covering_range_explicit - When true, the covering range must be one
15444 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
15445 /// possibly modified since. When false, the covering range must not
15446 /// be one of the ranges explicitly created via
15447 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
15448 /// a covering range not created via AddSecureHeapPhysicalRange(). The
15449 /// covering range is typically the entire physical range (or a range
15450 /// which covers even more) of a heap configured by the TEE and whose
15451 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
15452 ///
15453 /// Ongoing DMA is not disrupted by this request.
15454 ///
15455 /// Errors:
15456 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15457 /// Unexpected heap.
15458 /// * UNSPECIFIED - generic internal error (such as in communication
15459 /// with TEE which doesn't generate zx_status_t errors).
15460 /// * other errors are possible, such as from communication failures or
15461 /// server propagation of failures.
15462 pub fn r#zero_sub_range(
15463 &self,
15464 mut payload: &SecureMemZeroSubRangeRequest,
15465 ___deadline: zx::MonotonicInstant,
15466 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
15467 let _response = self.client.send_query::<
15468 SecureMemZeroSubRangeRequest,
15469 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15470 SecureMemMarker,
15471 >(
15472 payload,
15473 0x5b25b7901a385ce5,
15474 fidl::encoding::DynamicFlags::FLEXIBLE,
15475 ___deadline,
15476 )?
15477 .into_result::<SecureMemMarker>("zero_sub_range")?;
15478 Ok(_response.map(|x| x))
15479 }
15480}
15481
15482#[cfg(target_os = "fuchsia")]
15483impl From<SecureMemSynchronousProxy> for zx::NullableHandle {
15484 fn from(value: SecureMemSynchronousProxy) -> Self {
15485 value.into_channel().into()
15486 }
15487}
15488
15489#[cfg(target_os = "fuchsia")]
15490impl From<fidl::Channel> for SecureMemSynchronousProxy {
15491 fn from(value: fidl::Channel) -> Self {
15492 Self::new(value)
15493 }
15494}
15495
15496#[cfg(target_os = "fuchsia")]
15497impl fidl::endpoints::FromClient for SecureMemSynchronousProxy {
15498 type Protocol = SecureMemMarker;
15499
15500 fn from_client(value: fidl::endpoints::ClientEnd<SecureMemMarker>) -> Self {
15501 Self::new(value.into_channel())
15502 }
15503}
15504
15505#[derive(Debug, Clone)]
15506pub struct SecureMemProxy {
15507 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
15508}
15509
15510impl fidl::endpoints::Proxy for SecureMemProxy {
15511 type Protocol = SecureMemMarker;
15512
15513 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
15514 Self::new(inner)
15515 }
15516
15517 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
15518 self.client.into_channel().map_err(|client| Self { client })
15519 }
15520
15521 fn as_channel(&self) -> &::fidl::AsyncChannel {
15522 self.client.as_channel()
15523 }
15524}
15525
15526impl SecureMemProxy {
15527 /// Create a new Proxy for fuchsia.sysmem2/SecureMem.
15528 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
15529 let protocol_name = <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
15530 Self { client: fidl::client::Client::new(channel, protocol_name) }
15531 }
15532
15533 /// Get a Stream of events from the remote end of the protocol.
15534 ///
15535 /// # Panics
15536 ///
15537 /// Panics if the event stream was already taken.
15538 pub fn take_event_stream(&self) -> SecureMemEventStream {
15539 SecureMemEventStream { event_receiver: self.client.take_event_receiver() }
15540 }
15541
15542 /// Gets the physical address and length of any secure heap whose physical
15543 /// range is configured via the TEE.
15544 ///
15545 /// Presently, these will be fixed physical addresses and lengths, with the
15546 /// location plumbed via the TEE.
15547 ///
15548 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
15549 /// when there isn't any special heap-specific per-VMO setup or teardown
15550 /// required.
15551 ///
15552 /// The physical range must be secured/protected by the TEE before the
15553 /// securemem driver responds to this request with success.
15554 ///
15555 /// Sysmem should only call this once. Returning zero heaps is not a
15556 /// failure.
15557 ///
15558 /// Errors:
15559 /// * PROTOCOL_DEVIATION - called more than once.
15560 /// * UNSPECIFIED - generic internal error (such as in communication
15561 /// with TEE which doesn't generate zx_status_t errors).
15562 /// * other errors are allowed; any other errors should be treated the same
15563 /// as UNSPECIFIED.
15564 pub fn r#get_physical_secure_heaps(
15565 &self,
15566 ) -> fidl::client::QueryResponseFut<
15567 SecureMemGetPhysicalSecureHeapsResult,
15568 fidl::encoding::DefaultFuchsiaResourceDialect,
15569 > {
15570 SecureMemProxyInterface::r#get_physical_secure_heaps(self)
15571 }
15572
15573 /// Gets information about any secure heaps whose physical pages are not
15574 /// configured by the TEE, but by sysmem.
15575 ///
15576 /// Sysmem should only call this once. Returning zero heaps is not a
15577 /// failure.
15578 ///
15579 /// Errors:
15580 /// * PROTOCOL_DEVIATION - called more than once.
15581 /// * UNSPECIFIED - generic internal error (such as in communication
15582 /// with TEE which doesn't generate zx_status_t errors).
15583 /// * other errors are allowed; any other errors should be treated the same
15584 /// as UNSPECIFIED.
15585 pub fn r#get_dynamic_secure_heaps(
15586 &self,
15587 ) -> fidl::client::QueryResponseFut<
15588 SecureMemGetDynamicSecureHeapsResult,
15589 fidl::encoding::DefaultFuchsiaResourceDialect,
15590 > {
15591 SecureMemProxyInterface::r#get_dynamic_secure_heaps(self)
15592 }
15593
15594 /// This request from sysmem to the securemem driver gets the properties of
15595 /// a protected/secure heap.
15596 ///
15597 /// This only handles heaps with a single contiguous physical extent.
15598 ///
15599 /// The heap's entire physical range is indicated in case this request needs
15600 /// some physical space to auto-detect how many ranges are REE-usable. Any
15601 /// temporary HW protection ranges will be deleted before this request
15602 /// completes.
15603 ///
15604 /// Errors:
15605 /// * UNSPECIFIED - generic internal error (such as in communication
15606 /// with TEE which doesn't generate zx_status_t errors).
15607 /// * other errors are allowed; any other errors should be treated the same
15608 /// as UNSPECIFIED.
15609 pub fn r#get_physical_secure_heap_properties(
15610 &self,
15611 mut payload: &SecureMemGetPhysicalSecureHeapPropertiesRequest,
15612 ) -> fidl::client::QueryResponseFut<
15613 SecureMemGetPhysicalSecureHeapPropertiesResult,
15614 fidl::encoding::DefaultFuchsiaResourceDialect,
15615 > {
15616 SecureMemProxyInterface::r#get_physical_secure_heap_properties(self, payload)
15617 }
15618
15619 /// This request from sysmem to the securemem driver conveys a physical
15620 /// range to add, for a heap whose physical range(s) are set up via
15621 /// sysmem.
15622 ///
15623 /// Only sysmem can call this because only sysmem is handed the client end
15624 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15625 /// securemem driver is the server end of this protocol.
15626 ///
15627 /// The securemem driver must configure all the covered offsets as protected
15628 /// before responding to this message with success.
15629 ///
15630 /// On failure, the securemem driver must ensure the protected range was not
15631 /// created.
15632 ///
15633 /// Sysmem must only call this up to once if dynamic_protection_ranges
15634 /// false.
15635 ///
15636 /// If dynamic_protection_ranges is true, sysmem can call this multiple
15637 /// times as long as the current number of ranges never exceeds
15638 /// max_protected_range_count.
15639 ///
15640 /// The caller must not attempt to add a range that matches an
15641 /// already-existing range. Added ranges can overlap each other as long as
15642 /// no two ranges match exactly.
15643 ///
15644 /// Errors:
15645 /// * PROTOCOL_DEVIATION - called more than once when
15646 /// !dynamic_protection_ranges. Adding a heap that would cause overall
15647 /// heap count to exceed max_protected_range_count. Unexpected heap, or
15648 /// range that doesn't conform to protected_range_granularity. See log.
15649 /// * UNSPECIFIED - generic internal error (such as in communication
15650 /// with TEE which doesn't generate zx_status_t errors).
15651 /// * other errors are possible, such as from communication failures or
15652 /// server propagation of failures.
15653 pub fn r#add_secure_heap_physical_range(
15654 &self,
15655 mut payload: &SecureMemAddSecureHeapPhysicalRangeRequest,
15656 ) -> fidl::client::QueryResponseFut<
15657 SecureMemAddSecureHeapPhysicalRangeResult,
15658 fidl::encoding::DefaultFuchsiaResourceDialect,
15659 > {
15660 SecureMemProxyInterface::r#add_secure_heap_physical_range(self, payload)
15661 }
15662
15663 /// This request from sysmem to the securemem driver conveys a physical
15664 /// range to delete, for a heap whose physical range(s) are set up via
15665 /// sysmem.
15666 ///
15667 /// Only sysmem can call this because only sysmem is handed the client end
15668 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15669 /// securemem driver is the server end of this protocol.
15670 ///
15671 /// The securemem driver must configure all the covered offsets as not
15672 /// protected before responding to this message with success.
15673 ///
15674 /// On failure, the securemem driver must ensure the protected range was not
15675 /// deleted.
15676 ///
15677 /// Sysmem must not call this if dynamic_protection_ranges false.
15678 ///
15679 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
15680 /// on various ranges that exist at the time of the call.
15681 ///
15682 /// If any portion of the range being deleted is not also covered by another
15683 /// protected range, then any ongoing DMA to any part of the entire range
15684 /// may be interrupted / may fail, potentially in a way that's disruptive to
15685 /// the entire system (bus lockup or similar, depending on device details).
15686 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
15687 /// any portion of the range being deleted, unless the caller has other
15688 /// active ranges covering every block of the range being deleted. Ongoing
15689 /// DMA to/from blocks outside the range being deleted is never impacted by
15690 /// the deletion.
15691 ///
15692 /// Errors:
15693 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15694 /// Unexpected heap, or range that doesn't conform to
15695 /// protected_range_granularity.
15696 /// * UNSPECIFIED - generic internal error (such as in communication
15697 /// with TEE which doesn't generate zx_status_t errors).
15698 /// * NOT_FOUND - the specified range is not found.
15699 /// * other errors are possible, such as from communication failures or
15700 /// server propagation of failures.
15701 pub fn r#delete_secure_heap_physical_range(
15702 &self,
15703 mut payload: &SecureMemDeleteSecureHeapPhysicalRangeRequest,
15704 ) -> fidl::client::QueryResponseFut<
15705 SecureMemDeleteSecureHeapPhysicalRangeResult,
15706 fidl::encoding::DefaultFuchsiaResourceDialect,
15707 > {
15708 SecureMemProxyInterface::r#delete_secure_heap_physical_range(self, payload)
15709 }
15710
15711 /// This request from sysmem to the securemem driver conveys a physical
15712 /// range to modify and its new base and length, for a heap whose physical
15713 /// range(s) are set up via sysmem.
15714 ///
15715 /// Only sysmem can call this because only sysmem is handed the client end
15716 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15717 /// securemem driver is the server end of this protocol.
15718 ///
15719 /// The securemem driver must configure the range to cover only the new
15720 /// offsets before responding to this message with success.
15721 ///
15722 /// On failure, the securemem driver must ensure the range was not changed.
15723 ///
15724 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
15725 /// must not call this if !is_mod_protected_range_available.
15726 ///
15727 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
15728 /// on various ranges that exist at the time of the call.
15729 ///
15730 /// The range must only be modified at one end or the other, but not both.
15731 /// If the range is getting shorter, and the un-covered blocks are not
15732 /// covered by other active ranges, any ongoing DMA to the entire range
15733 /// that's geting shorter may fail in a way that disrupts the entire system
15734 /// (bus lockup or similar), so the caller must ensure that no DMA is
15735 /// ongoing to any portion of a range that is getting shorter, unless the
15736 /// blocks being un-covered by the modification to this range are all
15737 /// covered by other active ranges, in which case no disruption to ongoing
15738 /// DMA will occur.
15739 ///
15740 /// If a range is modified to become <= zero length, the range is deleted.
15741 ///
15742 /// Errors:
15743 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15744 /// Unexpected heap, or old_range or new_range that doesn't conform to
15745 /// protected_range_granularity, or old_range and new_range differ in
15746 /// both begin and end (disallowed).
15747 /// * UNSPECIFIED - generic internal error (such as in communication
15748 /// with TEE which doesn't generate zx_status_t errors).
15749 /// * NOT_FOUND - the specified range is not found.
15750 /// * other errors are possible, such as from communication failures or
15751 /// server propagation of failures.
15752 pub fn r#modify_secure_heap_physical_range(
15753 &self,
15754 mut payload: &SecureMemModifySecureHeapPhysicalRangeRequest,
15755 ) -> fidl::client::QueryResponseFut<
15756 SecureMemModifySecureHeapPhysicalRangeResult,
15757 fidl::encoding::DefaultFuchsiaResourceDialect,
15758 > {
15759 SecureMemProxyInterface::r#modify_secure_heap_physical_range(self, payload)
15760 }
15761
15762 /// Zero a sub-range of a currently-existing physical range added via
15763 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
15764 /// exactly one physical range, and must not overlap with any other
15765 /// physical range.
15766 ///
15767 /// is_covering_range_explicit - When true, the covering range must be one
15768 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
15769 /// possibly modified since. When false, the covering range must not
15770 /// be one of the ranges explicitly created via
15771 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
15772 /// a covering range not created via AddSecureHeapPhysicalRange(). The
15773 /// covering range is typically the entire physical range (or a range
15774 /// which covers even more) of a heap configured by the TEE and whose
15775 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
15776 ///
15777 /// Ongoing DMA is not disrupted by this request.
15778 ///
15779 /// Errors:
15780 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15781 /// Unexpected heap.
15782 /// * UNSPECIFIED - generic internal error (such as in communication
15783 /// with TEE which doesn't generate zx_status_t errors).
15784 /// * other errors are possible, such as from communication failures or
15785 /// server propagation of failures.
15786 pub fn r#zero_sub_range(
15787 &self,
15788 mut payload: &SecureMemZeroSubRangeRequest,
15789 ) -> fidl::client::QueryResponseFut<
15790 SecureMemZeroSubRangeResult,
15791 fidl::encoding::DefaultFuchsiaResourceDialect,
15792 > {
15793 SecureMemProxyInterface::r#zero_sub_range(self, payload)
15794 }
15795}
15796
15797impl SecureMemProxyInterface for SecureMemProxy {
15798 type GetPhysicalSecureHeapsResponseFut = fidl::client::QueryResponseFut<
15799 SecureMemGetPhysicalSecureHeapsResult,
15800 fidl::encoding::DefaultFuchsiaResourceDialect,
15801 >;
15802 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut {
15803 fn _decode(
15804 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15805 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
15806 let _response = fidl::client::decode_transaction_body::<
15807 fidl::encoding::FlexibleResultType<SecureMemGetPhysicalSecureHeapsResponse, Error>,
15808 fidl::encoding::DefaultFuchsiaResourceDialect,
15809 0x38716300592073e3,
15810 >(_buf?)?
15811 .into_result::<SecureMemMarker>("get_physical_secure_heaps")?;
15812 Ok(_response.map(|x| x))
15813 }
15814 self.client.send_query_and_decode::<
15815 fidl::encoding::EmptyPayload,
15816 SecureMemGetPhysicalSecureHeapsResult,
15817 >(
15818 (),
15819 0x38716300592073e3,
15820 fidl::encoding::DynamicFlags::FLEXIBLE,
15821 _decode,
15822 )
15823 }
15824
15825 type GetDynamicSecureHeapsResponseFut = fidl::client::QueryResponseFut<
15826 SecureMemGetDynamicSecureHeapsResult,
15827 fidl::encoding::DefaultFuchsiaResourceDialect,
15828 >;
15829 fn r#get_dynamic_secure_heaps(&self) -> Self::GetDynamicSecureHeapsResponseFut {
15830 fn _decode(
15831 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15832 ) -> Result<SecureMemGetDynamicSecureHeapsResult, fidl::Error> {
15833 let _response = fidl::client::decode_transaction_body::<
15834 fidl::encoding::FlexibleResultType<SecureMemGetDynamicSecureHeapsResponse, Error>,
15835 fidl::encoding::DefaultFuchsiaResourceDialect,
15836 0x1190847f99952834,
15837 >(_buf?)?
15838 .into_result::<SecureMemMarker>("get_dynamic_secure_heaps")?;
15839 Ok(_response.map(|x| x))
15840 }
15841 self.client.send_query_and_decode::<
15842 fidl::encoding::EmptyPayload,
15843 SecureMemGetDynamicSecureHeapsResult,
15844 >(
15845 (),
15846 0x1190847f99952834,
15847 fidl::encoding::DynamicFlags::FLEXIBLE,
15848 _decode,
15849 )
15850 }
15851
15852 type GetPhysicalSecureHeapPropertiesResponseFut = fidl::client::QueryResponseFut<
15853 SecureMemGetPhysicalSecureHeapPropertiesResult,
15854 fidl::encoding::DefaultFuchsiaResourceDialect,
15855 >;
15856 fn r#get_physical_secure_heap_properties(
15857 &self,
15858 mut payload: &SecureMemGetPhysicalSecureHeapPropertiesRequest,
15859 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut {
15860 fn _decode(
15861 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15862 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
15863 let _response = fidl::client::decode_transaction_body::<
15864 fidl::encoding::FlexibleResultType<
15865 SecureMemGetPhysicalSecureHeapPropertiesResponse,
15866 Error,
15867 >,
15868 fidl::encoding::DefaultFuchsiaResourceDialect,
15869 0xc6f06889009c7bc,
15870 >(_buf?)?
15871 .into_result::<SecureMemMarker>("get_physical_secure_heap_properties")?;
15872 Ok(_response.map(|x| x))
15873 }
15874 self.client.send_query_and_decode::<
15875 SecureMemGetPhysicalSecureHeapPropertiesRequest,
15876 SecureMemGetPhysicalSecureHeapPropertiesResult,
15877 >(
15878 payload,
15879 0xc6f06889009c7bc,
15880 fidl::encoding::DynamicFlags::FLEXIBLE,
15881 _decode,
15882 )
15883 }
15884
15885 type AddSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
15886 SecureMemAddSecureHeapPhysicalRangeResult,
15887 fidl::encoding::DefaultFuchsiaResourceDialect,
15888 >;
15889 fn r#add_secure_heap_physical_range(
15890 &self,
15891 mut payload: &SecureMemAddSecureHeapPhysicalRangeRequest,
15892 ) -> Self::AddSecureHeapPhysicalRangeResponseFut {
15893 fn _decode(
15894 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15895 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
15896 let _response = fidl::client::decode_transaction_body::<
15897 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15898 fidl::encoding::DefaultFuchsiaResourceDialect,
15899 0x35f695b9b6c7217a,
15900 >(_buf?)?
15901 .into_result::<SecureMemMarker>("add_secure_heap_physical_range")?;
15902 Ok(_response.map(|x| x))
15903 }
15904 self.client.send_query_and_decode::<
15905 SecureMemAddSecureHeapPhysicalRangeRequest,
15906 SecureMemAddSecureHeapPhysicalRangeResult,
15907 >(
15908 payload,
15909 0x35f695b9b6c7217a,
15910 fidl::encoding::DynamicFlags::FLEXIBLE,
15911 _decode,
15912 )
15913 }
15914
15915 type DeleteSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
15916 SecureMemDeleteSecureHeapPhysicalRangeResult,
15917 fidl::encoding::DefaultFuchsiaResourceDialect,
15918 >;
15919 fn r#delete_secure_heap_physical_range(
15920 &self,
15921 mut payload: &SecureMemDeleteSecureHeapPhysicalRangeRequest,
15922 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut {
15923 fn _decode(
15924 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15925 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
15926 let _response = fidl::client::decode_transaction_body::<
15927 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15928 fidl::encoding::DefaultFuchsiaResourceDialect,
15929 0xeaa58c650264c9e,
15930 >(_buf?)?
15931 .into_result::<SecureMemMarker>("delete_secure_heap_physical_range")?;
15932 Ok(_response.map(|x| x))
15933 }
15934 self.client.send_query_and_decode::<
15935 SecureMemDeleteSecureHeapPhysicalRangeRequest,
15936 SecureMemDeleteSecureHeapPhysicalRangeResult,
15937 >(
15938 payload,
15939 0xeaa58c650264c9e,
15940 fidl::encoding::DynamicFlags::FLEXIBLE,
15941 _decode,
15942 )
15943 }
15944
15945 type ModifySecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
15946 SecureMemModifySecureHeapPhysicalRangeResult,
15947 fidl::encoding::DefaultFuchsiaResourceDialect,
15948 >;
15949 fn r#modify_secure_heap_physical_range(
15950 &self,
15951 mut payload: &SecureMemModifySecureHeapPhysicalRangeRequest,
15952 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut {
15953 fn _decode(
15954 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15955 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
15956 let _response = fidl::client::decode_transaction_body::<
15957 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15958 fidl::encoding::DefaultFuchsiaResourceDialect,
15959 0x60b7448aa1187734,
15960 >(_buf?)?
15961 .into_result::<SecureMemMarker>("modify_secure_heap_physical_range")?;
15962 Ok(_response.map(|x| x))
15963 }
15964 self.client.send_query_and_decode::<
15965 SecureMemModifySecureHeapPhysicalRangeRequest,
15966 SecureMemModifySecureHeapPhysicalRangeResult,
15967 >(
15968 payload,
15969 0x60b7448aa1187734,
15970 fidl::encoding::DynamicFlags::FLEXIBLE,
15971 _decode,
15972 )
15973 }
15974
15975 type ZeroSubRangeResponseFut = fidl::client::QueryResponseFut<
15976 SecureMemZeroSubRangeResult,
15977 fidl::encoding::DefaultFuchsiaResourceDialect,
15978 >;
15979 fn r#zero_sub_range(
15980 &self,
15981 mut payload: &SecureMemZeroSubRangeRequest,
15982 ) -> Self::ZeroSubRangeResponseFut {
15983 fn _decode(
15984 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15985 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
15986 let _response = fidl::client::decode_transaction_body::<
15987 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15988 fidl::encoding::DefaultFuchsiaResourceDialect,
15989 0x5b25b7901a385ce5,
15990 >(_buf?)?
15991 .into_result::<SecureMemMarker>("zero_sub_range")?;
15992 Ok(_response.map(|x| x))
15993 }
15994 self.client
15995 .send_query_and_decode::<SecureMemZeroSubRangeRequest, SecureMemZeroSubRangeResult>(
15996 payload,
15997 0x5b25b7901a385ce5,
15998 fidl::encoding::DynamicFlags::FLEXIBLE,
15999 _decode,
16000 )
16001 }
16002}
16003
16004pub struct SecureMemEventStream {
16005 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
16006}
16007
16008impl std::marker::Unpin for SecureMemEventStream {}
16009
16010impl futures::stream::FusedStream for SecureMemEventStream {
16011 fn is_terminated(&self) -> bool {
16012 self.event_receiver.is_terminated()
16013 }
16014}
16015
16016impl futures::Stream for SecureMemEventStream {
16017 type Item = Result<SecureMemEvent, fidl::Error>;
16018
16019 fn poll_next(
16020 mut self: std::pin::Pin<&mut Self>,
16021 cx: &mut std::task::Context<'_>,
16022 ) -> std::task::Poll<Option<Self::Item>> {
16023 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
16024 &mut self.event_receiver,
16025 cx
16026 )?) {
16027 Some(buf) => std::task::Poll::Ready(Some(SecureMemEvent::decode(buf))),
16028 None => std::task::Poll::Ready(None),
16029 }
16030 }
16031}
16032
16033#[derive(Debug)]
16034pub enum SecureMemEvent {
16035 #[non_exhaustive]
16036 _UnknownEvent {
16037 /// Ordinal of the event that was sent.
16038 ordinal: u64,
16039 },
16040}
16041
16042impl SecureMemEvent {
16043 /// Decodes a message buffer as a [`SecureMemEvent`].
16044 fn decode(
16045 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
16046 ) -> Result<SecureMemEvent, fidl::Error> {
16047 let (bytes, _handles) = buf.split_mut();
16048 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
16049 debug_assert_eq!(tx_header.tx_id, 0);
16050 match tx_header.ordinal {
16051 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
16052 Ok(SecureMemEvent::_UnknownEvent { ordinal: tx_header.ordinal })
16053 }
16054 _ => Err(fidl::Error::UnknownOrdinal {
16055 ordinal: tx_header.ordinal,
16056 protocol_name: <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
16057 }),
16058 }
16059 }
16060}
16061
16062/// A Stream of incoming requests for fuchsia.sysmem2/SecureMem.
16063pub struct SecureMemRequestStream {
16064 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
16065 is_terminated: bool,
16066}
16067
16068impl std::marker::Unpin for SecureMemRequestStream {}
16069
16070impl futures::stream::FusedStream for SecureMemRequestStream {
16071 fn is_terminated(&self) -> bool {
16072 self.is_terminated
16073 }
16074}
16075
16076impl fidl::endpoints::RequestStream for SecureMemRequestStream {
16077 type Protocol = SecureMemMarker;
16078 type ControlHandle = SecureMemControlHandle;
16079
16080 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
16081 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
16082 }
16083
16084 fn control_handle(&self) -> Self::ControlHandle {
16085 SecureMemControlHandle { inner: self.inner.clone() }
16086 }
16087
16088 fn into_inner(
16089 self,
16090 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
16091 {
16092 (self.inner, self.is_terminated)
16093 }
16094
16095 fn from_inner(
16096 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
16097 is_terminated: bool,
16098 ) -> Self {
16099 Self { inner, is_terminated }
16100 }
16101}
16102
16103impl futures::Stream for SecureMemRequestStream {
16104 type Item = Result<SecureMemRequest, fidl::Error>;
16105
16106 fn poll_next(
16107 mut self: std::pin::Pin<&mut Self>,
16108 cx: &mut std::task::Context<'_>,
16109 ) -> std::task::Poll<Option<Self::Item>> {
16110 let this = &mut *self;
16111 if this.inner.check_shutdown(cx) {
16112 this.is_terminated = true;
16113 return std::task::Poll::Ready(None);
16114 }
16115 if this.is_terminated {
16116 panic!("polled SecureMemRequestStream after completion");
16117 }
16118 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
16119 |bytes, handles| {
16120 match this.inner.channel().read_etc(cx, bytes, handles) {
16121 std::task::Poll::Ready(Ok(())) => {}
16122 std::task::Poll::Pending => return std::task::Poll::Pending,
16123 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
16124 this.is_terminated = true;
16125 return std::task::Poll::Ready(None);
16126 }
16127 std::task::Poll::Ready(Err(e)) => {
16128 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
16129 e.into(),
16130 ))));
16131 }
16132 }
16133
16134 // A message has been received from the channel
16135 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
16136
16137 std::task::Poll::Ready(Some(match header.ordinal {
16138 0x38716300592073e3 => {
16139 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16140 let mut req = fidl::new_empty!(
16141 fidl::encoding::EmptyPayload,
16142 fidl::encoding::DefaultFuchsiaResourceDialect
16143 );
16144 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
16145 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16146 Ok(SecureMemRequest::GetPhysicalSecureHeaps {
16147 responder: SecureMemGetPhysicalSecureHeapsResponder {
16148 control_handle: std::mem::ManuallyDrop::new(control_handle),
16149 tx_id: header.tx_id,
16150 },
16151 })
16152 }
16153 0x1190847f99952834 => {
16154 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16155 let mut req = fidl::new_empty!(
16156 fidl::encoding::EmptyPayload,
16157 fidl::encoding::DefaultFuchsiaResourceDialect
16158 );
16159 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
16160 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16161 Ok(SecureMemRequest::GetDynamicSecureHeaps {
16162 responder: SecureMemGetDynamicSecureHeapsResponder {
16163 control_handle: std::mem::ManuallyDrop::new(control_handle),
16164 tx_id: header.tx_id,
16165 },
16166 })
16167 }
16168 0xc6f06889009c7bc => {
16169 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16170 let mut req = fidl::new_empty!(
16171 SecureMemGetPhysicalSecureHeapPropertiesRequest,
16172 fidl::encoding::DefaultFuchsiaResourceDialect
16173 );
16174 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemGetPhysicalSecureHeapPropertiesRequest>(&header, _body_bytes, handles, &mut req)?;
16175 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16176 Ok(SecureMemRequest::GetPhysicalSecureHeapProperties {
16177 payload: req,
16178 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder {
16179 control_handle: std::mem::ManuallyDrop::new(control_handle),
16180 tx_id: header.tx_id,
16181 },
16182 })
16183 }
16184 0x35f695b9b6c7217a => {
16185 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16186 let mut req = fidl::new_empty!(
16187 SecureMemAddSecureHeapPhysicalRangeRequest,
16188 fidl::encoding::DefaultFuchsiaResourceDialect
16189 );
16190 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemAddSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
16191 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16192 Ok(SecureMemRequest::AddSecureHeapPhysicalRange {
16193 payload: req,
16194 responder: SecureMemAddSecureHeapPhysicalRangeResponder {
16195 control_handle: std::mem::ManuallyDrop::new(control_handle),
16196 tx_id: header.tx_id,
16197 },
16198 })
16199 }
16200 0xeaa58c650264c9e => {
16201 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16202 let mut req = fidl::new_empty!(
16203 SecureMemDeleteSecureHeapPhysicalRangeRequest,
16204 fidl::encoding::DefaultFuchsiaResourceDialect
16205 );
16206 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemDeleteSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
16207 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16208 Ok(SecureMemRequest::DeleteSecureHeapPhysicalRange {
16209 payload: req,
16210 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder {
16211 control_handle: std::mem::ManuallyDrop::new(control_handle),
16212 tx_id: header.tx_id,
16213 },
16214 })
16215 }
16216 0x60b7448aa1187734 => {
16217 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16218 let mut req = fidl::new_empty!(
16219 SecureMemModifySecureHeapPhysicalRangeRequest,
16220 fidl::encoding::DefaultFuchsiaResourceDialect
16221 );
16222 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemModifySecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
16223 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16224 Ok(SecureMemRequest::ModifySecureHeapPhysicalRange {
16225 payload: req,
16226 responder: SecureMemModifySecureHeapPhysicalRangeResponder {
16227 control_handle: std::mem::ManuallyDrop::new(control_handle),
16228 tx_id: header.tx_id,
16229 },
16230 })
16231 }
16232 0x5b25b7901a385ce5 => {
16233 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16234 let mut req = fidl::new_empty!(
16235 SecureMemZeroSubRangeRequest,
16236 fidl::encoding::DefaultFuchsiaResourceDialect
16237 );
16238 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemZeroSubRangeRequest>(&header, _body_bytes, handles, &mut req)?;
16239 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16240 Ok(SecureMemRequest::ZeroSubRange {
16241 payload: req,
16242 responder: SecureMemZeroSubRangeResponder {
16243 control_handle: std::mem::ManuallyDrop::new(control_handle),
16244 tx_id: header.tx_id,
16245 },
16246 })
16247 }
16248 _ if header.tx_id == 0
16249 && header
16250 .dynamic_flags()
16251 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
16252 {
16253 Ok(SecureMemRequest::_UnknownMethod {
16254 ordinal: header.ordinal,
16255 control_handle: SecureMemControlHandle { inner: this.inner.clone() },
16256 method_type: fidl::MethodType::OneWay,
16257 })
16258 }
16259 _ if header
16260 .dynamic_flags()
16261 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
16262 {
16263 this.inner.send_framework_err(
16264 fidl::encoding::FrameworkErr::UnknownMethod,
16265 header.tx_id,
16266 header.ordinal,
16267 header.dynamic_flags(),
16268 (bytes, handles),
16269 )?;
16270 Ok(SecureMemRequest::_UnknownMethod {
16271 ordinal: header.ordinal,
16272 control_handle: SecureMemControlHandle { inner: this.inner.clone() },
16273 method_type: fidl::MethodType::TwoWay,
16274 })
16275 }
16276 _ => Err(fidl::Error::UnknownOrdinal {
16277 ordinal: header.ordinal,
16278 protocol_name:
16279 <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
16280 }),
16281 }))
16282 },
16283 )
16284 }
16285}
16286
16287/// SecureMem
16288///
16289/// The client is sysmem. The server is securemem driver.
16290///
16291/// TEE - Trusted Execution Environment.
16292///
16293/// REE - Rich Execution Environment.
16294///
16295/// Enables sysmem to call the securemem driver to get any secure heaps
16296/// configured via the TEE (or via the securemem driver), and set any physical
16297/// secure heaps configured via sysmem.
16298///
16299/// Presently, dynamically-allocated secure heaps are configured via sysmem, as
16300/// it starts quite early during boot and can successfully reserve contiguous
16301/// physical memory. Presently, fixed-location secure heaps are configured via
16302/// TEE, as the plumbing goes from the bootloader to the TEE. However, this
16303/// protocol intentionally doesn't care which heaps are dynamically-allocated
16304/// and which are fixed-location.
16305#[derive(Debug)]
16306pub enum SecureMemRequest {
16307 /// Gets the physical address and length of any secure heap whose physical
16308 /// range is configured via the TEE.
16309 ///
16310 /// Presently, these will be fixed physical addresses and lengths, with the
16311 /// location plumbed via the TEE.
16312 ///
16313 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
16314 /// when there isn't any special heap-specific per-VMO setup or teardown
16315 /// required.
16316 ///
16317 /// The physical range must be secured/protected by the TEE before the
16318 /// securemem driver responds to this request with success.
16319 ///
16320 /// Sysmem should only call this once. Returning zero heaps is not a
16321 /// failure.
16322 ///
16323 /// Errors:
16324 /// * PROTOCOL_DEVIATION - called more than once.
16325 /// * UNSPECIFIED - generic internal error (such as in communication
16326 /// with TEE which doesn't generate zx_status_t errors).
16327 /// * other errors are allowed; any other errors should be treated the same
16328 /// as UNSPECIFIED.
16329 GetPhysicalSecureHeaps { responder: SecureMemGetPhysicalSecureHeapsResponder },
16330 /// Gets information about any secure heaps whose physical pages are not
16331 /// configured by the TEE, but by sysmem.
16332 ///
16333 /// Sysmem should only call this once. Returning zero heaps is not a
16334 /// failure.
16335 ///
16336 /// Errors:
16337 /// * PROTOCOL_DEVIATION - called more than once.
16338 /// * UNSPECIFIED - generic internal error (such as in communication
16339 /// with TEE which doesn't generate zx_status_t errors).
16340 /// * other errors are allowed; any other errors should be treated the same
16341 /// as UNSPECIFIED.
16342 GetDynamicSecureHeaps { responder: SecureMemGetDynamicSecureHeapsResponder },
16343 /// This request from sysmem to the securemem driver gets the properties of
16344 /// a protected/secure heap.
16345 ///
16346 /// This only handles heaps with a single contiguous physical extent.
16347 ///
16348 /// The heap's entire physical range is indicated in case this request needs
16349 /// some physical space to auto-detect how many ranges are REE-usable. Any
16350 /// temporary HW protection ranges will be deleted before this request
16351 /// completes.
16352 ///
16353 /// Errors:
16354 /// * UNSPECIFIED - generic internal error (such as in communication
16355 /// with TEE which doesn't generate zx_status_t errors).
16356 /// * other errors are allowed; any other errors should be treated the same
16357 /// as UNSPECIFIED.
16358 GetPhysicalSecureHeapProperties {
16359 payload: SecureMemGetPhysicalSecureHeapPropertiesRequest,
16360 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder,
16361 },
16362 /// This request from sysmem to the securemem driver conveys a physical
16363 /// range to add, for a heap whose physical range(s) are set up via
16364 /// sysmem.
16365 ///
16366 /// Only sysmem can call this because only sysmem is handed the client end
16367 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
16368 /// securemem driver is the server end of this protocol.
16369 ///
16370 /// The securemem driver must configure all the covered offsets as protected
16371 /// before responding to this message with success.
16372 ///
16373 /// On failure, the securemem driver must ensure the protected range was not
16374 /// created.
16375 ///
16376 /// Sysmem must only call this up to once if dynamic_protection_ranges
16377 /// false.
16378 ///
16379 /// If dynamic_protection_ranges is true, sysmem can call this multiple
16380 /// times as long as the current number of ranges never exceeds
16381 /// max_protected_range_count.
16382 ///
16383 /// The caller must not attempt to add a range that matches an
16384 /// already-existing range. Added ranges can overlap each other as long as
16385 /// no two ranges match exactly.
16386 ///
16387 /// Errors:
16388 /// * PROTOCOL_DEVIATION - called more than once when
16389 /// !dynamic_protection_ranges. Adding a heap that would cause overall
16390 /// heap count to exceed max_protected_range_count. Unexpected heap, or
16391 /// range that doesn't conform to protected_range_granularity. See log.
16392 /// * UNSPECIFIED - generic internal error (such as in communication
16393 /// with TEE which doesn't generate zx_status_t errors).
16394 /// * other errors are possible, such as from communication failures or
16395 /// server propagation of failures.
16396 AddSecureHeapPhysicalRange {
16397 payload: SecureMemAddSecureHeapPhysicalRangeRequest,
16398 responder: SecureMemAddSecureHeapPhysicalRangeResponder,
16399 },
16400 /// This request from sysmem to the securemem driver conveys a physical
16401 /// range to delete, for a heap whose physical range(s) are set up via
16402 /// sysmem.
16403 ///
16404 /// Only sysmem can call this because only sysmem is handed the client end
16405 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
16406 /// securemem driver is the server end of this protocol.
16407 ///
16408 /// The securemem driver must configure all the covered offsets as not
16409 /// protected before responding to this message with success.
16410 ///
16411 /// On failure, the securemem driver must ensure the protected range was not
16412 /// deleted.
16413 ///
16414 /// Sysmem must not call this if dynamic_protection_ranges false.
16415 ///
16416 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
16417 /// on various ranges that exist at the time of the call.
16418 ///
16419 /// If any portion of the range being deleted is not also covered by another
16420 /// protected range, then any ongoing DMA to any part of the entire range
16421 /// may be interrupted / may fail, potentially in a way that's disruptive to
16422 /// the entire system (bus lockup or similar, depending on device details).
16423 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
16424 /// any portion of the range being deleted, unless the caller has other
16425 /// active ranges covering every block of the range being deleted. Ongoing
16426 /// DMA to/from blocks outside the range being deleted is never impacted by
16427 /// the deletion.
16428 ///
16429 /// Errors:
16430 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
16431 /// Unexpected heap, or range that doesn't conform to
16432 /// protected_range_granularity.
16433 /// * UNSPECIFIED - generic internal error (such as in communication
16434 /// with TEE which doesn't generate zx_status_t errors).
16435 /// * NOT_FOUND - the specified range is not found.
16436 /// * other errors are possible, such as from communication failures or
16437 /// server propagation of failures.
16438 DeleteSecureHeapPhysicalRange {
16439 payload: SecureMemDeleteSecureHeapPhysicalRangeRequest,
16440 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder,
16441 },
16442 /// This request from sysmem to the securemem driver conveys a physical
16443 /// range to modify and its new base and length, for a heap whose physical
16444 /// range(s) are set up via sysmem.
16445 ///
16446 /// Only sysmem can call this because only sysmem is handed the client end
16447 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
16448 /// securemem driver is the server end of this protocol.
16449 ///
16450 /// The securemem driver must configure the range to cover only the new
16451 /// offsets before responding to this message with success.
16452 ///
16453 /// On failure, the securemem driver must ensure the range was not changed.
16454 ///
16455 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
16456 /// must not call this if !is_mod_protected_range_available.
16457 ///
16458 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
16459 /// on various ranges that exist at the time of the call.
16460 ///
16461 /// The range must only be modified at one end or the other, but not both.
16462 /// If the range is getting shorter, and the un-covered blocks are not
16463 /// covered by other active ranges, any ongoing DMA to the entire range
16464 /// that's geting shorter may fail in a way that disrupts the entire system
16465 /// (bus lockup or similar), so the caller must ensure that no DMA is
16466 /// ongoing to any portion of a range that is getting shorter, unless the
16467 /// blocks being un-covered by the modification to this range are all
16468 /// covered by other active ranges, in which case no disruption to ongoing
16469 /// DMA will occur.
16470 ///
16471 /// If a range is modified to become <= zero length, the range is deleted.
16472 ///
16473 /// Errors:
16474 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
16475 /// Unexpected heap, or old_range or new_range that doesn't conform to
16476 /// protected_range_granularity, or old_range and new_range differ in
16477 /// both begin and end (disallowed).
16478 /// * UNSPECIFIED - generic internal error (such as in communication
16479 /// with TEE which doesn't generate zx_status_t errors).
16480 /// * NOT_FOUND - the specified range is not found.
16481 /// * other errors are possible, such as from communication failures or
16482 /// server propagation of failures.
16483 ModifySecureHeapPhysicalRange {
16484 payload: SecureMemModifySecureHeapPhysicalRangeRequest,
16485 responder: SecureMemModifySecureHeapPhysicalRangeResponder,
16486 },
16487 /// Zero a sub-range of a currently-existing physical range added via
16488 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
16489 /// exactly one physical range, and must not overlap with any other
16490 /// physical range.
16491 ///
16492 /// is_covering_range_explicit - When true, the covering range must be one
16493 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
16494 /// possibly modified since. When false, the covering range must not
16495 /// be one of the ranges explicitly created via
16496 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
16497 /// a covering range not created via AddSecureHeapPhysicalRange(). The
16498 /// covering range is typically the entire physical range (or a range
16499 /// which covers even more) of a heap configured by the TEE and whose
16500 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
16501 ///
16502 /// Ongoing DMA is not disrupted by this request.
16503 ///
16504 /// Errors:
16505 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
16506 /// Unexpected heap.
16507 /// * UNSPECIFIED - generic internal error (such as in communication
16508 /// with TEE which doesn't generate zx_status_t errors).
16509 /// * other errors are possible, such as from communication failures or
16510 /// server propagation of failures.
16511 ZeroSubRange {
16512 payload: SecureMemZeroSubRangeRequest,
16513 responder: SecureMemZeroSubRangeResponder,
16514 },
16515 /// An interaction was received which does not match any known method.
16516 #[non_exhaustive]
16517 _UnknownMethod {
16518 /// Ordinal of the method that was called.
16519 ordinal: u64,
16520 control_handle: SecureMemControlHandle,
16521 method_type: fidl::MethodType,
16522 },
16523}
16524
16525impl SecureMemRequest {
16526 #[allow(irrefutable_let_patterns)]
16527 pub fn into_get_physical_secure_heaps(
16528 self,
16529 ) -> Option<(SecureMemGetPhysicalSecureHeapsResponder)> {
16530 if let SecureMemRequest::GetPhysicalSecureHeaps { responder } = self {
16531 Some((responder))
16532 } else {
16533 None
16534 }
16535 }
16536
16537 #[allow(irrefutable_let_patterns)]
16538 pub fn into_get_dynamic_secure_heaps(
16539 self,
16540 ) -> Option<(SecureMemGetDynamicSecureHeapsResponder)> {
16541 if let SecureMemRequest::GetDynamicSecureHeaps { responder } = self {
16542 Some((responder))
16543 } else {
16544 None
16545 }
16546 }
16547
16548 #[allow(irrefutable_let_patterns)]
16549 pub fn into_get_physical_secure_heap_properties(
16550 self,
16551 ) -> Option<(
16552 SecureMemGetPhysicalSecureHeapPropertiesRequest,
16553 SecureMemGetPhysicalSecureHeapPropertiesResponder,
16554 )> {
16555 if let SecureMemRequest::GetPhysicalSecureHeapProperties { payload, responder } = self {
16556 Some((payload, responder))
16557 } else {
16558 None
16559 }
16560 }
16561
16562 #[allow(irrefutable_let_patterns)]
16563 pub fn into_add_secure_heap_physical_range(
16564 self,
16565 ) -> Option<(
16566 SecureMemAddSecureHeapPhysicalRangeRequest,
16567 SecureMemAddSecureHeapPhysicalRangeResponder,
16568 )> {
16569 if let SecureMemRequest::AddSecureHeapPhysicalRange { payload, responder } = self {
16570 Some((payload, responder))
16571 } else {
16572 None
16573 }
16574 }
16575
16576 #[allow(irrefutable_let_patterns)]
16577 pub fn into_delete_secure_heap_physical_range(
16578 self,
16579 ) -> Option<(
16580 SecureMemDeleteSecureHeapPhysicalRangeRequest,
16581 SecureMemDeleteSecureHeapPhysicalRangeResponder,
16582 )> {
16583 if let SecureMemRequest::DeleteSecureHeapPhysicalRange { payload, responder } = self {
16584 Some((payload, responder))
16585 } else {
16586 None
16587 }
16588 }
16589
16590 #[allow(irrefutable_let_patterns)]
16591 pub fn into_modify_secure_heap_physical_range(
16592 self,
16593 ) -> Option<(
16594 SecureMemModifySecureHeapPhysicalRangeRequest,
16595 SecureMemModifySecureHeapPhysicalRangeResponder,
16596 )> {
16597 if let SecureMemRequest::ModifySecureHeapPhysicalRange { payload, responder } = self {
16598 Some((payload, responder))
16599 } else {
16600 None
16601 }
16602 }
16603
16604 #[allow(irrefutable_let_patterns)]
16605 pub fn into_zero_sub_range(
16606 self,
16607 ) -> Option<(SecureMemZeroSubRangeRequest, SecureMemZeroSubRangeResponder)> {
16608 if let SecureMemRequest::ZeroSubRange { payload, responder } = self {
16609 Some((payload, responder))
16610 } else {
16611 None
16612 }
16613 }
16614
16615 /// Name of the method defined in FIDL
16616 pub fn method_name(&self) -> &'static str {
16617 match *self {
16618 SecureMemRequest::GetPhysicalSecureHeaps { .. } => "get_physical_secure_heaps",
16619 SecureMemRequest::GetDynamicSecureHeaps { .. } => "get_dynamic_secure_heaps",
16620 SecureMemRequest::GetPhysicalSecureHeapProperties { .. } => {
16621 "get_physical_secure_heap_properties"
16622 }
16623 SecureMemRequest::AddSecureHeapPhysicalRange { .. } => "add_secure_heap_physical_range",
16624 SecureMemRequest::DeleteSecureHeapPhysicalRange { .. } => {
16625 "delete_secure_heap_physical_range"
16626 }
16627 SecureMemRequest::ModifySecureHeapPhysicalRange { .. } => {
16628 "modify_secure_heap_physical_range"
16629 }
16630 SecureMemRequest::ZeroSubRange { .. } => "zero_sub_range",
16631 SecureMemRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
16632 "unknown one-way method"
16633 }
16634 SecureMemRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
16635 "unknown two-way method"
16636 }
16637 }
16638 }
16639}
16640
16641#[derive(Debug, Clone)]
16642pub struct SecureMemControlHandle {
16643 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
16644}
16645
16646impl SecureMemControlHandle {
16647 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
16648 self.inner.shutdown_with_epitaph(status.into())
16649 }
16650}
16651
16652impl fidl::endpoints::ControlHandle for SecureMemControlHandle {
16653 fn shutdown(&self) {
16654 self.inner.shutdown()
16655 }
16656
16657 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
16658 self.inner.shutdown_with_epitaph(status)
16659 }
16660
16661 fn is_closed(&self) -> bool {
16662 self.inner.channel().is_closed()
16663 }
16664 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
16665 self.inner.channel().on_closed()
16666 }
16667
16668 #[cfg(target_os = "fuchsia")]
16669 fn signal_peer(
16670 &self,
16671 clear_mask: zx::Signals,
16672 set_mask: zx::Signals,
16673 ) -> Result<(), zx_status::Status> {
16674 use fidl::Peered;
16675 self.inner.channel().signal_peer(clear_mask, set_mask)
16676 }
16677}
16678
16679impl SecureMemControlHandle {}
16680
16681#[must_use = "FIDL methods require a response to be sent"]
16682#[derive(Debug)]
16683pub struct SecureMemGetPhysicalSecureHeapsResponder {
16684 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
16685 tx_id: u32,
16686}
16687
16688/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
16689/// if the responder is dropped without sending a response, so that the client
16690/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
16691impl std::ops::Drop for SecureMemGetPhysicalSecureHeapsResponder {
16692 fn drop(&mut self) {
16693 self.control_handle.shutdown();
16694 // Safety: drops once, never accessed again
16695 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16696 }
16697}
16698
16699impl fidl::endpoints::Responder for SecureMemGetPhysicalSecureHeapsResponder {
16700 type ControlHandle = SecureMemControlHandle;
16701
16702 fn control_handle(&self) -> &SecureMemControlHandle {
16703 &self.control_handle
16704 }
16705
16706 fn drop_without_shutdown(mut self) {
16707 // Safety: drops once, never accessed again due to mem::forget
16708 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16709 // Prevent Drop from running (which would shut down the channel)
16710 std::mem::forget(self);
16711 }
16712}
16713
16714impl SecureMemGetPhysicalSecureHeapsResponder {
16715 /// Sends a response to the FIDL transaction.
16716 ///
16717 /// Sets the channel to shutdown if an error occurs.
16718 pub fn send(
16719 self,
16720 mut result: Result<&SecureMemGetPhysicalSecureHeapsResponse, Error>,
16721 ) -> Result<(), fidl::Error> {
16722 let _result = self.send_raw(result);
16723 if _result.is_err() {
16724 self.control_handle.shutdown();
16725 }
16726 self.drop_without_shutdown();
16727 _result
16728 }
16729
16730 /// Similar to "send" but does not shutdown the channel if an error occurs.
16731 pub fn send_no_shutdown_on_err(
16732 self,
16733 mut result: Result<&SecureMemGetPhysicalSecureHeapsResponse, Error>,
16734 ) -> Result<(), fidl::Error> {
16735 let _result = self.send_raw(result);
16736 self.drop_without_shutdown();
16737 _result
16738 }
16739
16740 fn send_raw(
16741 &self,
16742 mut result: Result<&SecureMemGetPhysicalSecureHeapsResponse, Error>,
16743 ) -> Result<(), fidl::Error> {
16744 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
16745 SecureMemGetPhysicalSecureHeapsResponse,
16746 Error,
16747 >>(
16748 fidl::encoding::FlexibleResult::new(result),
16749 self.tx_id,
16750 0x38716300592073e3,
16751 fidl::encoding::DynamicFlags::FLEXIBLE,
16752 )
16753 }
16754}
16755
16756#[must_use = "FIDL methods require a response to be sent"]
16757#[derive(Debug)]
16758pub struct SecureMemGetDynamicSecureHeapsResponder {
16759 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
16760 tx_id: u32,
16761}
16762
16763/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
16764/// if the responder is dropped without sending a response, so that the client
16765/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
16766impl std::ops::Drop for SecureMemGetDynamicSecureHeapsResponder {
16767 fn drop(&mut self) {
16768 self.control_handle.shutdown();
16769 // Safety: drops once, never accessed again
16770 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16771 }
16772}
16773
16774impl fidl::endpoints::Responder for SecureMemGetDynamicSecureHeapsResponder {
16775 type ControlHandle = SecureMemControlHandle;
16776
16777 fn control_handle(&self) -> &SecureMemControlHandle {
16778 &self.control_handle
16779 }
16780
16781 fn drop_without_shutdown(mut self) {
16782 // Safety: drops once, never accessed again due to mem::forget
16783 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16784 // Prevent Drop from running (which would shut down the channel)
16785 std::mem::forget(self);
16786 }
16787}
16788
16789impl SecureMemGetDynamicSecureHeapsResponder {
16790 /// Sends a response to the FIDL transaction.
16791 ///
16792 /// Sets the channel to shutdown if an error occurs.
16793 pub fn send(
16794 self,
16795 mut result: Result<&SecureMemGetDynamicSecureHeapsResponse, Error>,
16796 ) -> Result<(), fidl::Error> {
16797 let _result = self.send_raw(result);
16798 if _result.is_err() {
16799 self.control_handle.shutdown();
16800 }
16801 self.drop_without_shutdown();
16802 _result
16803 }
16804
16805 /// Similar to "send" but does not shutdown the channel if an error occurs.
16806 pub fn send_no_shutdown_on_err(
16807 self,
16808 mut result: Result<&SecureMemGetDynamicSecureHeapsResponse, Error>,
16809 ) -> Result<(), fidl::Error> {
16810 let _result = self.send_raw(result);
16811 self.drop_without_shutdown();
16812 _result
16813 }
16814
16815 fn send_raw(
16816 &self,
16817 mut result: Result<&SecureMemGetDynamicSecureHeapsResponse, Error>,
16818 ) -> Result<(), fidl::Error> {
16819 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
16820 SecureMemGetDynamicSecureHeapsResponse,
16821 Error,
16822 >>(
16823 fidl::encoding::FlexibleResult::new(result),
16824 self.tx_id,
16825 0x1190847f99952834,
16826 fidl::encoding::DynamicFlags::FLEXIBLE,
16827 )
16828 }
16829}
16830
16831#[must_use = "FIDL methods require a response to be sent"]
16832#[derive(Debug)]
16833pub struct SecureMemGetPhysicalSecureHeapPropertiesResponder {
16834 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
16835 tx_id: u32,
16836}
16837
16838/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
16839/// if the responder is dropped without sending a response, so that the client
16840/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
16841impl std::ops::Drop for SecureMemGetPhysicalSecureHeapPropertiesResponder {
16842 fn drop(&mut self) {
16843 self.control_handle.shutdown();
16844 // Safety: drops once, never accessed again
16845 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16846 }
16847}
16848
16849impl fidl::endpoints::Responder for SecureMemGetPhysicalSecureHeapPropertiesResponder {
16850 type ControlHandle = SecureMemControlHandle;
16851
16852 fn control_handle(&self) -> &SecureMemControlHandle {
16853 &self.control_handle
16854 }
16855
16856 fn drop_without_shutdown(mut self) {
16857 // Safety: drops once, never accessed again due to mem::forget
16858 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16859 // Prevent Drop from running (which would shut down the channel)
16860 std::mem::forget(self);
16861 }
16862}
16863
16864impl SecureMemGetPhysicalSecureHeapPropertiesResponder {
16865 /// Sends a response to the FIDL transaction.
16866 ///
16867 /// Sets the channel to shutdown if an error occurs.
16868 pub fn send(
16869 self,
16870 mut result: Result<&SecureMemGetPhysicalSecureHeapPropertiesResponse, Error>,
16871 ) -> Result<(), fidl::Error> {
16872 let _result = self.send_raw(result);
16873 if _result.is_err() {
16874 self.control_handle.shutdown();
16875 }
16876 self.drop_without_shutdown();
16877 _result
16878 }
16879
16880 /// Similar to "send" but does not shutdown the channel if an error occurs.
16881 pub fn send_no_shutdown_on_err(
16882 self,
16883 mut result: Result<&SecureMemGetPhysicalSecureHeapPropertiesResponse, Error>,
16884 ) -> Result<(), fidl::Error> {
16885 let _result = self.send_raw(result);
16886 self.drop_without_shutdown();
16887 _result
16888 }
16889
16890 fn send_raw(
16891 &self,
16892 mut result: Result<&SecureMemGetPhysicalSecureHeapPropertiesResponse, Error>,
16893 ) -> Result<(), fidl::Error> {
16894 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
16895 SecureMemGetPhysicalSecureHeapPropertiesResponse,
16896 Error,
16897 >>(
16898 fidl::encoding::FlexibleResult::new(result),
16899 self.tx_id,
16900 0xc6f06889009c7bc,
16901 fidl::encoding::DynamicFlags::FLEXIBLE,
16902 )
16903 }
16904}
16905
16906#[must_use = "FIDL methods require a response to be sent"]
16907#[derive(Debug)]
16908pub struct SecureMemAddSecureHeapPhysicalRangeResponder {
16909 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
16910 tx_id: u32,
16911}
16912
16913/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
16914/// if the responder is dropped without sending a response, so that the client
16915/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
16916impl std::ops::Drop for SecureMemAddSecureHeapPhysicalRangeResponder {
16917 fn drop(&mut self) {
16918 self.control_handle.shutdown();
16919 // Safety: drops once, never accessed again
16920 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16921 }
16922}
16923
16924impl fidl::endpoints::Responder for SecureMemAddSecureHeapPhysicalRangeResponder {
16925 type ControlHandle = SecureMemControlHandle;
16926
16927 fn control_handle(&self) -> &SecureMemControlHandle {
16928 &self.control_handle
16929 }
16930
16931 fn drop_without_shutdown(mut self) {
16932 // Safety: drops once, never accessed again due to mem::forget
16933 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16934 // Prevent Drop from running (which would shut down the channel)
16935 std::mem::forget(self);
16936 }
16937}
16938
16939impl SecureMemAddSecureHeapPhysicalRangeResponder {
16940 /// Sends a response to the FIDL transaction.
16941 ///
16942 /// Sets the channel to shutdown if an error occurs.
16943 pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
16944 let _result = self.send_raw(result);
16945 if _result.is_err() {
16946 self.control_handle.shutdown();
16947 }
16948 self.drop_without_shutdown();
16949 _result
16950 }
16951
16952 /// Similar to "send" but does not shutdown the channel if an error occurs.
16953 pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
16954 let _result = self.send_raw(result);
16955 self.drop_without_shutdown();
16956 _result
16957 }
16958
16959 fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
16960 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
16961 fidl::encoding::EmptyStruct,
16962 Error,
16963 >>(
16964 fidl::encoding::FlexibleResult::new(result),
16965 self.tx_id,
16966 0x35f695b9b6c7217a,
16967 fidl::encoding::DynamicFlags::FLEXIBLE,
16968 )
16969 }
16970}
16971
16972#[must_use = "FIDL methods require a response to be sent"]
16973#[derive(Debug)]
16974pub struct SecureMemDeleteSecureHeapPhysicalRangeResponder {
16975 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
16976 tx_id: u32,
16977}
16978
16979/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
16980/// if the responder is dropped without sending a response, so that the client
16981/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
16982impl std::ops::Drop for SecureMemDeleteSecureHeapPhysicalRangeResponder {
16983 fn drop(&mut self) {
16984 self.control_handle.shutdown();
16985 // Safety: drops once, never accessed again
16986 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16987 }
16988}
16989
16990impl fidl::endpoints::Responder for SecureMemDeleteSecureHeapPhysicalRangeResponder {
16991 type ControlHandle = SecureMemControlHandle;
16992
16993 fn control_handle(&self) -> &SecureMemControlHandle {
16994 &self.control_handle
16995 }
16996
16997 fn drop_without_shutdown(mut self) {
16998 // Safety: drops once, never accessed again due to mem::forget
16999 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
17000 // Prevent Drop from running (which would shut down the channel)
17001 std::mem::forget(self);
17002 }
17003}
17004
17005impl SecureMemDeleteSecureHeapPhysicalRangeResponder {
17006 /// Sends a response to the FIDL transaction.
17007 ///
17008 /// Sets the channel to shutdown if an error occurs.
17009 pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17010 let _result = self.send_raw(result);
17011 if _result.is_err() {
17012 self.control_handle.shutdown();
17013 }
17014 self.drop_without_shutdown();
17015 _result
17016 }
17017
17018 /// Similar to "send" but does not shutdown the channel if an error occurs.
17019 pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17020 let _result = self.send_raw(result);
17021 self.drop_without_shutdown();
17022 _result
17023 }
17024
17025 fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17026 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
17027 fidl::encoding::EmptyStruct,
17028 Error,
17029 >>(
17030 fidl::encoding::FlexibleResult::new(result),
17031 self.tx_id,
17032 0xeaa58c650264c9e,
17033 fidl::encoding::DynamicFlags::FLEXIBLE,
17034 )
17035 }
17036}
17037
17038#[must_use = "FIDL methods require a response to be sent"]
17039#[derive(Debug)]
17040pub struct SecureMemModifySecureHeapPhysicalRangeResponder {
17041 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
17042 tx_id: u32,
17043}
17044
17045/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
17046/// if the responder is dropped without sending a response, so that the client
17047/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
17048impl std::ops::Drop for SecureMemModifySecureHeapPhysicalRangeResponder {
17049 fn drop(&mut self) {
17050 self.control_handle.shutdown();
17051 // Safety: drops once, never accessed again
17052 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
17053 }
17054}
17055
17056impl fidl::endpoints::Responder for SecureMemModifySecureHeapPhysicalRangeResponder {
17057 type ControlHandle = SecureMemControlHandle;
17058
17059 fn control_handle(&self) -> &SecureMemControlHandle {
17060 &self.control_handle
17061 }
17062
17063 fn drop_without_shutdown(mut self) {
17064 // Safety: drops once, never accessed again due to mem::forget
17065 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
17066 // Prevent Drop from running (which would shut down the channel)
17067 std::mem::forget(self);
17068 }
17069}
17070
17071impl SecureMemModifySecureHeapPhysicalRangeResponder {
17072 /// Sends a response to the FIDL transaction.
17073 ///
17074 /// Sets the channel to shutdown if an error occurs.
17075 pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17076 let _result = self.send_raw(result);
17077 if _result.is_err() {
17078 self.control_handle.shutdown();
17079 }
17080 self.drop_without_shutdown();
17081 _result
17082 }
17083
17084 /// Similar to "send" but does not shutdown the channel if an error occurs.
17085 pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17086 let _result = self.send_raw(result);
17087 self.drop_without_shutdown();
17088 _result
17089 }
17090
17091 fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17092 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
17093 fidl::encoding::EmptyStruct,
17094 Error,
17095 >>(
17096 fidl::encoding::FlexibleResult::new(result),
17097 self.tx_id,
17098 0x60b7448aa1187734,
17099 fidl::encoding::DynamicFlags::FLEXIBLE,
17100 )
17101 }
17102}
17103
17104#[must_use = "FIDL methods require a response to be sent"]
17105#[derive(Debug)]
17106pub struct SecureMemZeroSubRangeResponder {
17107 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
17108 tx_id: u32,
17109}
17110
17111/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
17112/// if the responder is dropped without sending a response, so that the client
17113/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
17114impl std::ops::Drop for SecureMemZeroSubRangeResponder {
17115 fn drop(&mut self) {
17116 self.control_handle.shutdown();
17117 // Safety: drops once, never accessed again
17118 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
17119 }
17120}
17121
17122impl fidl::endpoints::Responder for SecureMemZeroSubRangeResponder {
17123 type ControlHandle = SecureMemControlHandle;
17124
17125 fn control_handle(&self) -> &SecureMemControlHandle {
17126 &self.control_handle
17127 }
17128
17129 fn drop_without_shutdown(mut self) {
17130 // Safety: drops once, never accessed again due to mem::forget
17131 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
17132 // Prevent Drop from running (which would shut down the channel)
17133 std::mem::forget(self);
17134 }
17135}
17136
17137impl SecureMemZeroSubRangeResponder {
17138 /// Sends a response to the FIDL transaction.
17139 ///
17140 /// Sets the channel to shutdown if an error occurs.
17141 pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17142 let _result = self.send_raw(result);
17143 if _result.is_err() {
17144 self.control_handle.shutdown();
17145 }
17146 self.drop_without_shutdown();
17147 _result
17148 }
17149
17150 /// Similar to "send" but does not shutdown the channel if an error occurs.
17151 pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17152 let _result = self.send_raw(result);
17153 self.drop_without_shutdown();
17154 _result
17155 }
17156
17157 fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17158 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
17159 fidl::encoding::EmptyStruct,
17160 Error,
17161 >>(
17162 fidl::encoding::FlexibleResult::new(result),
17163 self.tx_id,
17164 0x5b25b7901a385ce5,
17165 fidl::encoding::DynamicFlags::FLEXIBLE,
17166 )
17167 }
17168}
17169
17170mod internal {
17171 use super::*;
17172
17173 impl AllocatorAllocateNonSharedCollectionRequest {
17174 #[inline(always)]
17175 fn max_ordinal_present(&self) -> u64 {
17176 if let Some(_) = self.collection_request {
17177 return 1;
17178 }
17179 0
17180 }
17181 }
17182
17183 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateNonSharedCollectionRequest {
17184 type Borrowed<'a> = &'a mut Self;
17185 fn take_or_borrow<'a>(
17186 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
17187 ) -> Self::Borrowed<'a> {
17188 value
17189 }
17190 }
17191
17192 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateNonSharedCollectionRequest {
17193 type Owned = Self;
17194
17195 #[inline(always)]
17196 fn inline_align(_context: fidl::encoding::Context) -> usize {
17197 8
17198 }
17199
17200 #[inline(always)]
17201 fn inline_size(_context: fidl::encoding::Context) -> usize {
17202 16
17203 }
17204 }
17205
17206 unsafe impl
17207 fidl::encoding::Encode<
17208 AllocatorAllocateNonSharedCollectionRequest,
17209 fidl::encoding::DefaultFuchsiaResourceDialect,
17210 > for &mut AllocatorAllocateNonSharedCollectionRequest
17211 {
17212 unsafe fn encode(
17213 self,
17214 encoder: &mut fidl::encoding::Encoder<
17215 '_,
17216 fidl::encoding::DefaultFuchsiaResourceDialect,
17217 >,
17218 offset: usize,
17219 mut depth: fidl::encoding::Depth,
17220 ) -> fidl::Result<()> {
17221 encoder.debug_check_bounds::<AllocatorAllocateNonSharedCollectionRequest>(offset);
17222 // Vector header
17223 let max_ordinal: u64 = self.max_ordinal_present();
17224 encoder.write_num(max_ordinal, offset);
17225 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
17226 // Calling encoder.out_of_line_offset(0) is not allowed.
17227 if max_ordinal == 0 {
17228 return Ok(());
17229 }
17230 depth.increment()?;
17231 let envelope_size = 8;
17232 let bytes_len = max_ordinal as usize * envelope_size;
17233 #[allow(unused_variables)]
17234 let offset = encoder.out_of_line_offset(bytes_len);
17235 let mut _prev_end_offset: usize = 0;
17236 if 1 > max_ordinal {
17237 return Ok(());
17238 }
17239
17240 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17241 // are envelope_size bytes.
17242 let cur_offset: usize = (1 - 1) * envelope_size;
17243
17244 // Zero reserved fields.
17245 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17246
17247 // Safety:
17248 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17249 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17250 // envelope_size bytes, there is always sufficient room.
17251 fidl::encoding::encode_in_envelope_optional::<fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>, fidl::encoding::DefaultFuchsiaResourceDialect>(
17252 self.collection_request.as_mut().map(<fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow),
17253 encoder, offset + cur_offset, depth
17254 )?;
17255
17256 _prev_end_offset = cur_offset + envelope_size;
17257
17258 Ok(())
17259 }
17260 }
17261
17262 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
17263 for AllocatorAllocateNonSharedCollectionRequest
17264 {
17265 #[inline(always)]
17266 fn new_empty() -> Self {
17267 Self::default()
17268 }
17269
17270 unsafe fn decode(
17271 &mut self,
17272 decoder: &mut fidl::encoding::Decoder<
17273 '_,
17274 fidl::encoding::DefaultFuchsiaResourceDialect,
17275 >,
17276 offset: usize,
17277 mut depth: fidl::encoding::Depth,
17278 ) -> fidl::Result<()> {
17279 decoder.debug_check_bounds::<Self>(offset);
17280 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
17281 None => return Err(fidl::Error::NotNullable),
17282 Some(len) => len,
17283 };
17284 // Calling decoder.out_of_line_offset(0) is not allowed.
17285 if len == 0 {
17286 return Ok(());
17287 };
17288 depth.increment()?;
17289 let envelope_size = 8;
17290 let bytes_len = len * envelope_size;
17291 let offset = decoder.out_of_line_offset(bytes_len)?;
17292 // Decode the envelope for each type.
17293 let mut _next_ordinal_to_read = 0;
17294 let mut next_offset = offset;
17295 let end_offset = offset + bytes_len;
17296 _next_ordinal_to_read += 1;
17297 if next_offset >= end_offset {
17298 return Ok(());
17299 }
17300
17301 // Decode unknown envelopes for gaps in ordinals.
17302 while _next_ordinal_to_read < 1 {
17303 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17304 _next_ordinal_to_read += 1;
17305 next_offset += envelope_size;
17306 }
17307
17308 let next_out_of_line = decoder.next_out_of_line();
17309 let handles_before = decoder.remaining_handles();
17310 if let Some((inlined, num_bytes, num_handles)) =
17311 fidl::encoding::decode_envelope_header(decoder, next_offset)?
17312 {
17313 let member_inline_size = <fidl::encoding::Endpoint<
17314 fidl::endpoints::ServerEnd<BufferCollectionMarker>,
17315 > as fidl::encoding::TypeMarker>::inline_size(
17316 decoder.context
17317 );
17318 if inlined != (member_inline_size <= 4) {
17319 return Err(fidl::Error::InvalidInlineBitInEnvelope);
17320 }
17321 let inner_offset;
17322 let mut inner_depth = depth.clone();
17323 if inlined {
17324 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
17325 inner_offset = next_offset;
17326 } else {
17327 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
17328 inner_depth.increment()?;
17329 }
17330 let val_ref = self.collection_request.get_or_insert_with(|| {
17331 fidl::new_empty!(
17332 fidl::encoding::Endpoint<
17333 fidl::endpoints::ServerEnd<BufferCollectionMarker>,
17334 >,
17335 fidl::encoding::DefaultFuchsiaResourceDialect
17336 )
17337 });
17338 fidl::decode!(
17339 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
17340 fidl::encoding::DefaultFuchsiaResourceDialect,
17341 val_ref,
17342 decoder,
17343 inner_offset,
17344 inner_depth
17345 )?;
17346 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
17347 {
17348 return Err(fidl::Error::InvalidNumBytesInEnvelope);
17349 }
17350 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
17351 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
17352 }
17353 }
17354
17355 next_offset += envelope_size;
17356
17357 // Decode the remaining unknown envelopes.
17358 while next_offset < end_offset {
17359 _next_ordinal_to_read += 1;
17360 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17361 next_offset += envelope_size;
17362 }
17363
17364 Ok(())
17365 }
17366 }
17367
17368 impl AllocatorAllocateSharedCollectionRequest {
17369 #[inline(always)]
17370 fn max_ordinal_present(&self) -> u64 {
17371 if let Some(_) = self.token_request {
17372 return 1;
17373 }
17374 0
17375 }
17376 }
17377
17378 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateSharedCollectionRequest {
17379 type Borrowed<'a> = &'a mut Self;
17380 fn take_or_borrow<'a>(
17381 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
17382 ) -> Self::Borrowed<'a> {
17383 value
17384 }
17385 }
17386
17387 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateSharedCollectionRequest {
17388 type Owned = Self;
17389
17390 #[inline(always)]
17391 fn inline_align(_context: fidl::encoding::Context) -> usize {
17392 8
17393 }
17394
17395 #[inline(always)]
17396 fn inline_size(_context: fidl::encoding::Context) -> usize {
17397 16
17398 }
17399 }
17400
17401 unsafe impl
17402 fidl::encoding::Encode<
17403 AllocatorAllocateSharedCollectionRequest,
17404 fidl::encoding::DefaultFuchsiaResourceDialect,
17405 > for &mut AllocatorAllocateSharedCollectionRequest
17406 {
17407 unsafe fn encode(
17408 self,
17409 encoder: &mut fidl::encoding::Encoder<
17410 '_,
17411 fidl::encoding::DefaultFuchsiaResourceDialect,
17412 >,
17413 offset: usize,
17414 mut depth: fidl::encoding::Depth,
17415 ) -> fidl::Result<()> {
17416 encoder.debug_check_bounds::<AllocatorAllocateSharedCollectionRequest>(offset);
17417 // Vector header
17418 let max_ordinal: u64 = self.max_ordinal_present();
17419 encoder.write_num(max_ordinal, offset);
17420 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
17421 // Calling encoder.out_of_line_offset(0) is not allowed.
17422 if max_ordinal == 0 {
17423 return Ok(());
17424 }
17425 depth.increment()?;
17426 let envelope_size = 8;
17427 let bytes_len = max_ordinal as usize * envelope_size;
17428 #[allow(unused_variables)]
17429 let offset = encoder.out_of_line_offset(bytes_len);
17430 let mut _prev_end_offset: usize = 0;
17431 if 1 > max_ordinal {
17432 return Ok(());
17433 }
17434
17435 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17436 // are envelope_size bytes.
17437 let cur_offset: usize = (1 - 1) * envelope_size;
17438
17439 // Zero reserved fields.
17440 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17441
17442 // Safety:
17443 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17444 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17445 // envelope_size bytes, there is always sufficient room.
17446 fidl::encoding::encode_in_envelope_optional::<
17447 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
17448 fidl::encoding::DefaultFuchsiaResourceDialect,
17449 >(
17450 self.token_request.as_mut().map(
17451 <fidl::encoding::Endpoint<
17452 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
17453 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
17454 ),
17455 encoder,
17456 offset + cur_offset,
17457 depth,
17458 )?;
17459
17460 _prev_end_offset = cur_offset + envelope_size;
17461
17462 Ok(())
17463 }
17464 }
17465
17466 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
17467 for AllocatorAllocateSharedCollectionRequest
17468 {
17469 #[inline(always)]
17470 fn new_empty() -> Self {
17471 Self::default()
17472 }
17473
17474 unsafe fn decode(
17475 &mut self,
17476 decoder: &mut fidl::encoding::Decoder<
17477 '_,
17478 fidl::encoding::DefaultFuchsiaResourceDialect,
17479 >,
17480 offset: usize,
17481 mut depth: fidl::encoding::Depth,
17482 ) -> fidl::Result<()> {
17483 decoder.debug_check_bounds::<Self>(offset);
17484 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
17485 None => return Err(fidl::Error::NotNullable),
17486 Some(len) => len,
17487 };
17488 // Calling decoder.out_of_line_offset(0) is not allowed.
17489 if len == 0 {
17490 return Ok(());
17491 };
17492 depth.increment()?;
17493 let envelope_size = 8;
17494 let bytes_len = len * envelope_size;
17495 let offset = decoder.out_of_line_offset(bytes_len)?;
17496 // Decode the envelope for each type.
17497 let mut _next_ordinal_to_read = 0;
17498 let mut next_offset = offset;
17499 let end_offset = offset + bytes_len;
17500 _next_ordinal_to_read += 1;
17501 if next_offset >= end_offset {
17502 return Ok(());
17503 }
17504
17505 // Decode unknown envelopes for gaps in ordinals.
17506 while _next_ordinal_to_read < 1 {
17507 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17508 _next_ordinal_to_read += 1;
17509 next_offset += envelope_size;
17510 }
17511
17512 let next_out_of_line = decoder.next_out_of_line();
17513 let handles_before = decoder.remaining_handles();
17514 if let Some((inlined, num_bytes, num_handles)) =
17515 fidl::encoding::decode_envelope_header(decoder, next_offset)?
17516 {
17517 let member_inline_size = <fidl::encoding::Endpoint<
17518 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
17519 > as fidl::encoding::TypeMarker>::inline_size(
17520 decoder.context
17521 );
17522 if inlined != (member_inline_size <= 4) {
17523 return Err(fidl::Error::InvalidInlineBitInEnvelope);
17524 }
17525 let inner_offset;
17526 let mut inner_depth = depth.clone();
17527 if inlined {
17528 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
17529 inner_offset = next_offset;
17530 } else {
17531 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
17532 inner_depth.increment()?;
17533 }
17534 let val_ref = self.token_request.get_or_insert_with(|| {
17535 fidl::new_empty!(
17536 fidl::encoding::Endpoint<
17537 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
17538 >,
17539 fidl::encoding::DefaultFuchsiaResourceDialect
17540 )
17541 });
17542 fidl::decode!(
17543 fidl::encoding::Endpoint<
17544 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
17545 >,
17546 fidl::encoding::DefaultFuchsiaResourceDialect,
17547 val_ref,
17548 decoder,
17549 inner_offset,
17550 inner_depth
17551 )?;
17552 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
17553 {
17554 return Err(fidl::Error::InvalidNumBytesInEnvelope);
17555 }
17556 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
17557 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
17558 }
17559 }
17560
17561 next_offset += envelope_size;
17562
17563 // Decode the remaining unknown envelopes.
17564 while next_offset < end_offset {
17565 _next_ordinal_to_read += 1;
17566 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17567 next_offset += envelope_size;
17568 }
17569
17570 Ok(())
17571 }
17572 }
17573
17574 impl AllocatorBindSharedCollectionRequest {
17575 #[inline(always)]
17576 fn max_ordinal_present(&self) -> u64 {
17577 if let Some(_) = self.buffer_collection_request {
17578 return 2;
17579 }
17580 if let Some(_) = self.token {
17581 return 1;
17582 }
17583 0
17584 }
17585 }
17586
17587 impl fidl::encoding::ResourceTypeMarker for AllocatorBindSharedCollectionRequest {
17588 type Borrowed<'a> = &'a mut Self;
17589 fn take_or_borrow<'a>(
17590 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
17591 ) -> Self::Borrowed<'a> {
17592 value
17593 }
17594 }
17595
17596 unsafe impl fidl::encoding::TypeMarker for AllocatorBindSharedCollectionRequest {
17597 type Owned = Self;
17598
17599 #[inline(always)]
17600 fn inline_align(_context: fidl::encoding::Context) -> usize {
17601 8
17602 }
17603
17604 #[inline(always)]
17605 fn inline_size(_context: fidl::encoding::Context) -> usize {
17606 16
17607 }
17608 }
17609
17610 unsafe impl
17611 fidl::encoding::Encode<
17612 AllocatorBindSharedCollectionRequest,
17613 fidl::encoding::DefaultFuchsiaResourceDialect,
17614 > for &mut AllocatorBindSharedCollectionRequest
17615 {
17616 unsafe fn encode(
17617 self,
17618 encoder: &mut fidl::encoding::Encoder<
17619 '_,
17620 fidl::encoding::DefaultFuchsiaResourceDialect,
17621 >,
17622 offset: usize,
17623 mut depth: fidl::encoding::Depth,
17624 ) -> fidl::Result<()> {
17625 encoder.debug_check_bounds::<AllocatorBindSharedCollectionRequest>(offset);
17626 // Vector header
17627 let max_ordinal: u64 = self.max_ordinal_present();
17628 encoder.write_num(max_ordinal, offset);
17629 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
17630 // Calling encoder.out_of_line_offset(0) is not allowed.
17631 if max_ordinal == 0 {
17632 return Ok(());
17633 }
17634 depth.increment()?;
17635 let envelope_size = 8;
17636 let bytes_len = max_ordinal as usize * envelope_size;
17637 #[allow(unused_variables)]
17638 let offset = encoder.out_of_line_offset(bytes_len);
17639 let mut _prev_end_offset: usize = 0;
17640 if 1 > max_ordinal {
17641 return Ok(());
17642 }
17643
17644 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17645 // are envelope_size bytes.
17646 let cur_offset: usize = (1 - 1) * envelope_size;
17647
17648 // Zero reserved fields.
17649 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17650
17651 // Safety:
17652 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17653 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17654 // envelope_size bytes, there is always sufficient room.
17655 fidl::encoding::encode_in_envelope_optional::<
17656 fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
17657 fidl::encoding::DefaultFuchsiaResourceDialect,
17658 >(
17659 self.token.as_mut().map(
17660 <fidl::encoding::Endpoint<
17661 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
17662 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
17663 ),
17664 encoder,
17665 offset + cur_offset,
17666 depth,
17667 )?;
17668
17669 _prev_end_offset = cur_offset + envelope_size;
17670 if 2 > max_ordinal {
17671 return Ok(());
17672 }
17673
17674 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17675 // are envelope_size bytes.
17676 let cur_offset: usize = (2 - 1) * envelope_size;
17677
17678 // Zero reserved fields.
17679 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17680
17681 // Safety:
17682 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17683 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17684 // envelope_size bytes, there is always sufficient room.
17685 fidl::encoding::encode_in_envelope_optional::<fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>, fidl::encoding::DefaultFuchsiaResourceDialect>(
17686 self.buffer_collection_request.as_mut().map(<fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow),
17687 encoder, offset + cur_offset, depth
17688 )?;
17689
17690 _prev_end_offset = cur_offset + envelope_size;
17691
17692 Ok(())
17693 }
17694 }
17695
17696 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
17697 for AllocatorBindSharedCollectionRequest
17698 {
17699 #[inline(always)]
17700 fn new_empty() -> Self {
17701 Self::default()
17702 }
17703
17704 unsafe fn decode(
17705 &mut self,
17706 decoder: &mut fidl::encoding::Decoder<
17707 '_,
17708 fidl::encoding::DefaultFuchsiaResourceDialect,
17709 >,
17710 offset: usize,
17711 mut depth: fidl::encoding::Depth,
17712 ) -> fidl::Result<()> {
17713 decoder.debug_check_bounds::<Self>(offset);
17714 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
17715 None => return Err(fidl::Error::NotNullable),
17716 Some(len) => len,
17717 };
17718 // Calling decoder.out_of_line_offset(0) is not allowed.
17719 if len == 0 {
17720 return Ok(());
17721 };
17722 depth.increment()?;
17723 let envelope_size = 8;
17724 let bytes_len = len * envelope_size;
17725 let offset = decoder.out_of_line_offset(bytes_len)?;
17726 // Decode the envelope for each type.
17727 let mut _next_ordinal_to_read = 0;
17728 let mut next_offset = offset;
17729 let end_offset = offset + bytes_len;
17730 _next_ordinal_to_read += 1;
17731 if next_offset >= end_offset {
17732 return Ok(());
17733 }
17734
17735 // Decode unknown envelopes for gaps in ordinals.
17736 while _next_ordinal_to_read < 1 {
17737 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17738 _next_ordinal_to_read += 1;
17739 next_offset += envelope_size;
17740 }
17741
17742 let next_out_of_line = decoder.next_out_of_line();
17743 let handles_before = decoder.remaining_handles();
17744 if let Some((inlined, num_bytes, num_handles)) =
17745 fidl::encoding::decode_envelope_header(decoder, next_offset)?
17746 {
17747 let member_inline_size = <fidl::encoding::Endpoint<
17748 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
17749 > as fidl::encoding::TypeMarker>::inline_size(
17750 decoder.context
17751 );
17752 if inlined != (member_inline_size <= 4) {
17753 return Err(fidl::Error::InvalidInlineBitInEnvelope);
17754 }
17755 let inner_offset;
17756 let mut inner_depth = depth.clone();
17757 if inlined {
17758 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
17759 inner_offset = next_offset;
17760 } else {
17761 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
17762 inner_depth.increment()?;
17763 }
17764 let val_ref = self.token.get_or_insert_with(|| {
17765 fidl::new_empty!(
17766 fidl::encoding::Endpoint<
17767 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
17768 >,
17769 fidl::encoding::DefaultFuchsiaResourceDialect
17770 )
17771 });
17772 fidl::decode!(
17773 fidl::encoding::Endpoint<
17774 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
17775 >,
17776 fidl::encoding::DefaultFuchsiaResourceDialect,
17777 val_ref,
17778 decoder,
17779 inner_offset,
17780 inner_depth
17781 )?;
17782 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
17783 {
17784 return Err(fidl::Error::InvalidNumBytesInEnvelope);
17785 }
17786 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
17787 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
17788 }
17789 }
17790
17791 next_offset += envelope_size;
17792 _next_ordinal_to_read += 1;
17793 if next_offset >= end_offset {
17794 return Ok(());
17795 }
17796
17797 // Decode unknown envelopes for gaps in ordinals.
17798 while _next_ordinal_to_read < 2 {
17799 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17800 _next_ordinal_to_read += 1;
17801 next_offset += envelope_size;
17802 }
17803
17804 let next_out_of_line = decoder.next_out_of_line();
17805 let handles_before = decoder.remaining_handles();
17806 if let Some((inlined, num_bytes, num_handles)) =
17807 fidl::encoding::decode_envelope_header(decoder, next_offset)?
17808 {
17809 let member_inline_size = <fidl::encoding::Endpoint<
17810 fidl::endpoints::ServerEnd<BufferCollectionMarker>,
17811 > as fidl::encoding::TypeMarker>::inline_size(
17812 decoder.context
17813 );
17814 if inlined != (member_inline_size <= 4) {
17815 return Err(fidl::Error::InvalidInlineBitInEnvelope);
17816 }
17817 let inner_offset;
17818 let mut inner_depth = depth.clone();
17819 if inlined {
17820 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
17821 inner_offset = next_offset;
17822 } else {
17823 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
17824 inner_depth.increment()?;
17825 }
17826 let val_ref = self.buffer_collection_request.get_or_insert_with(|| {
17827 fidl::new_empty!(
17828 fidl::encoding::Endpoint<
17829 fidl::endpoints::ServerEnd<BufferCollectionMarker>,
17830 >,
17831 fidl::encoding::DefaultFuchsiaResourceDialect
17832 )
17833 });
17834 fidl::decode!(
17835 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
17836 fidl::encoding::DefaultFuchsiaResourceDialect,
17837 val_ref,
17838 decoder,
17839 inner_offset,
17840 inner_depth
17841 )?;
17842 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
17843 {
17844 return Err(fidl::Error::InvalidNumBytesInEnvelope);
17845 }
17846 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
17847 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
17848 }
17849 }
17850
17851 next_offset += envelope_size;
17852
17853 // Decode the remaining unknown envelopes.
17854 while next_offset < end_offset {
17855 _next_ordinal_to_read += 1;
17856 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17857 next_offset += envelope_size;
17858 }
17859
17860 Ok(())
17861 }
17862 }
17863
17864 impl AllocatorGetVmoInfoRequest {
17865 #[inline(always)]
17866 fn max_ordinal_present(&self) -> u64 {
17867 if let Some(_) = self.vmo_settings_to_check_ignore_size {
17868 return 6;
17869 }
17870 if let Some(_) = self.vmo_settings_to_check {
17871 return 5;
17872 }
17873 if let Some(_) = self.constraints_to_check {
17874 return 4;
17875 }
17876 if let Some(_) = self.need_single_buffer_settings {
17877 return 3;
17878 }
17879 if let Some(_) = self.need_weak {
17880 return 2;
17881 }
17882 if let Some(_) = self.vmo {
17883 return 1;
17884 }
17885 0
17886 }
17887 }
17888
17889 impl fidl::encoding::ResourceTypeMarker for AllocatorGetVmoInfoRequest {
17890 type Borrowed<'a> = &'a mut Self;
17891 fn take_or_borrow<'a>(
17892 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
17893 ) -> Self::Borrowed<'a> {
17894 value
17895 }
17896 }
17897
17898 unsafe impl fidl::encoding::TypeMarker for AllocatorGetVmoInfoRequest {
17899 type Owned = Self;
17900
17901 #[inline(always)]
17902 fn inline_align(_context: fidl::encoding::Context) -> usize {
17903 8
17904 }
17905
17906 #[inline(always)]
17907 fn inline_size(_context: fidl::encoding::Context) -> usize {
17908 16
17909 }
17910 }
17911
17912 unsafe impl
17913 fidl::encoding::Encode<
17914 AllocatorGetVmoInfoRequest,
17915 fidl::encoding::DefaultFuchsiaResourceDialect,
17916 > for &mut AllocatorGetVmoInfoRequest
17917 {
17918 unsafe fn encode(
17919 self,
17920 encoder: &mut fidl::encoding::Encoder<
17921 '_,
17922 fidl::encoding::DefaultFuchsiaResourceDialect,
17923 >,
17924 offset: usize,
17925 mut depth: fidl::encoding::Depth,
17926 ) -> fidl::Result<()> {
17927 encoder.debug_check_bounds::<AllocatorGetVmoInfoRequest>(offset);
17928 // Vector header
17929 let max_ordinal: u64 = self.max_ordinal_present();
17930 encoder.write_num(max_ordinal, offset);
17931 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
17932 // Calling encoder.out_of_line_offset(0) is not allowed.
17933 if max_ordinal == 0 {
17934 return Ok(());
17935 }
17936 depth.increment()?;
17937 let envelope_size = 8;
17938 let bytes_len = max_ordinal as usize * envelope_size;
17939 #[allow(unused_variables)]
17940 let offset = encoder.out_of_line_offset(bytes_len);
17941 let mut _prev_end_offset: usize = 0;
17942 if 1 > max_ordinal {
17943 return Ok(());
17944 }
17945
17946 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17947 // are envelope_size bytes.
17948 let cur_offset: usize = (1 - 1) * envelope_size;
17949
17950 // Zero reserved fields.
17951 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17952
17953 // Safety:
17954 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17955 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17956 // envelope_size bytes, there is always sufficient room.
17957 fidl::encoding::encode_in_envelope_optional::<
17958 fidl::encoding::HandleType<
17959 fidl::Vmo,
17960 { fidl::ObjectType::VMO.into_raw() },
17961 2147483648,
17962 >,
17963 fidl::encoding::DefaultFuchsiaResourceDialect,
17964 >(
17965 self.vmo.as_mut().map(
17966 <fidl::encoding::HandleType<
17967 fidl::Vmo,
17968 { fidl::ObjectType::VMO.into_raw() },
17969 2147483648,
17970 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
17971 ),
17972 encoder,
17973 offset + cur_offset,
17974 depth,
17975 )?;
17976
17977 _prev_end_offset = cur_offset + envelope_size;
17978 if 2 > max_ordinal {
17979 return Ok(());
17980 }
17981
17982 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17983 // are envelope_size bytes.
17984 let cur_offset: usize = (2 - 1) * envelope_size;
17985
17986 // Zero reserved fields.
17987 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17988
17989 // Safety:
17990 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17991 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17992 // envelope_size bytes, there is always sufficient room.
17993 fidl::encoding::encode_in_envelope_optional::<
17994 bool,
17995 fidl::encoding::DefaultFuchsiaResourceDialect,
17996 >(
17997 self.need_weak.as_ref().map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
17998 encoder,
17999 offset + cur_offset,
18000 depth,
18001 )?;
18002
18003 _prev_end_offset = cur_offset + envelope_size;
18004 if 3 > max_ordinal {
18005 return Ok(());
18006 }
18007
18008 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18009 // are envelope_size bytes.
18010 let cur_offset: usize = (3 - 1) * envelope_size;
18011
18012 // Zero reserved fields.
18013 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18014
18015 // Safety:
18016 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18017 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18018 // envelope_size bytes, there is always sufficient room.
18019 fidl::encoding::encode_in_envelope_optional::<
18020 bool,
18021 fidl::encoding::DefaultFuchsiaResourceDialect,
18022 >(
18023 self.need_single_buffer_settings
18024 .as_ref()
18025 .map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
18026 encoder,
18027 offset + cur_offset,
18028 depth,
18029 )?;
18030
18031 _prev_end_offset = cur_offset + envelope_size;
18032 if 4 > max_ordinal {
18033 return Ok(());
18034 }
18035
18036 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18037 // are envelope_size bytes.
18038 let cur_offset: usize = (4 - 1) * envelope_size;
18039
18040 // Zero reserved fields.
18041 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18042
18043 // Safety:
18044 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18045 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18046 // envelope_size bytes, there is always sufficient room.
18047 fidl::encoding::encode_in_envelope_optional::<
18048 BufferCollectionConstraints,
18049 fidl::encoding::DefaultFuchsiaResourceDialect,
18050 >(
18051 self.constraints_to_check
18052 .as_ref()
18053 .map(<BufferCollectionConstraints as fidl::encoding::ValueTypeMarker>::borrow),
18054 encoder,
18055 offset + cur_offset,
18056 depth,
18057 )?;
18058
18059 _prev_end_offset = cur_offset + envelope_size;
18060 if 5 > max_ordinal {
18061 return Ok(());
18062 }
18063
18064 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18065 // are envelope_size bytes.
18066 let cur_offset: usize = (5 - 1) * envelope_size;
18067
18068 // Zero reserved fields.
18069 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18070
18071 // Safety:
18072 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18073 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18074 // envelope_size bytes, there is always sufficient room.
18075 fidl::encoding::encode_in_envelope_optional::<
18076 fidl::encoding::HandleType<
18077 fidl::Vmo,
18078 { fidl::ObjectType::VMO.into_raw() },
18079 2147483648,
18080 >,
18081 fidl::encoding::DefaultFuchsiaResourceDialect,
18082 >(
18083 self.vmo_settings_to_check.as_mut().map(
18084 <fidl::encoding::HandleType<
18085 fidl::Vmo,
18086 { fidl::ObjectType::VMO.into_raw() },
18087 2147483648,
18088 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
18089 ),
18090 encoder,
18091 offset + cur_offset,
18092 depth,
18093 )?;
18094
18095 _prev_end_offset = cur_offset + envelope_size;
18096 if 6 > max_ordinal {
18097 return Ok(());
18098 }
18099
18100 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18101 // are envelope_size bytes.
18102 let cur_offset: usize = (6 - 1) * envelope_size;
18103
18104 // Zero reserved fields.
18105 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18106
18107 // Safety:
18108 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18109 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18110 // envelope_size bytes, there is always sufficient room.
18111 fidl::encoding::encode_in_envelope_optional::<
18112 bool,
18113 fidl::encoding::DefaultFuchsiaResourceDialect,
18114 >(
18115 self.vmo_settings_to_check_ignore_size
18116 .as_ref()
18117 .map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
18118 encoder,
18119 offset + cur_offset,
18120 depth,
18121 )?;
18122
18123 _prev_end_offset = cur_offset + envelope_size;
18124
18125 Ok(())
18126 }
18127 }
18128
18129 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
18130 for AllocatorGetVmoInfoRequest
18131 {
18132 #[inline(always)]
18133 fn new_empty() -> Self {
18134 Self::default()
18135 }
18136
18137 unsafe fn decode(
18138 &mut self,
18139 decoder: &mut fidl::encoding::Decoder<
18140 '_,
18141 fidl::encoding::DefaultFuchsiaResourceDialect,
18142 >,
18143 offset: usize,
18144 mut depth: fidl::encoding::Depth,
18145 ) -> fidl::Result<()> {
18146 decoder.debug_check_bounds::<Self>(offset);
18147 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
18148 None => return Err(fidl::Error::NotNullable),
18149 Some(len) => len,
18150 };
18151 // Calling decoder.out_of_line_offset(0) is not allowed.
18152 if len == 0 {
18153 return Ok(());
18154 };
18155 depth.increment()?;
18156 let envelope_size = 8;
18157 let bytes_len = len * envelope_size;
18158 let offset = decoder.out_of_line_offset(bytes_len)?;
18159 // Decode the envelope for each type.
18160 let mut _next_ordinal_to_read = 0;
18161 let mut next_offset = offset;
18162 let end_offset = offset + bytes_len;
18163 _next_ordinal_to_read += 1;
18164 if next_offset >= end_offset {
18165 return Ok(());
18166 }
18167
18168 // Decode unknown envelopes for gaps in ordinals.
18169 while _next_ordinal_to_read < 1 {
18170 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18171 _next_ordinal_to_read += 1;
18172 next_offset += envelope_size;
18173 }
18174
18175 let next_out_of_line = decoder.next_out_of_line();
18176 let handles_before = decoder.remaining_handles();
18177 if let Some((inlined, num_bytes, num_handles)) =
18178 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18179 {
18180 let member_inline_size = <fidl::encoding::HandleType<
18181 fidl::Vmo,
18182 { fidl::ObjectType::VMO.into_raw() },
18183 2147483648,
18184 > as fidl::encoding::TypeMarker>::inline_size(
18185 decoder.context
18186 );
18187 if inlined != (member_inline_size <= 4) {
18188 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18189 }
18190 let inner_offset;
18191 let mut inner_depth = depth.clone();
18192 if inlined {
18193 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18194 inner_offset = next_offset;
18195 } else {
18196 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18197 inner_depth.increment()?;
18198 }
18199 let val_ref =
18200 self.vmo.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
18201 fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
18202 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18203 {
18204 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18205 }
18206 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18207 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18208 }
18209 }
18210
18211 next_offset += envelope_size;
18212 _next_ordinal_to_read += 1;
18213 if next_offset >= end_offset {
18214 return Ok(());
18215 }
18216
18217 // Decode unknown envelopes for gaps in ordinals.
18218 while _next_ordinal_to_read < 2 {
18219 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18220 _next_ordinal_to_read += 1;
18221 next_offset += envelope_size;
18222 }
18223
18224 let next_out_of_line = decoder.next_out_of_line();
18225 let handles_before = decoder.remaining_handles();
18226 if let Some((inlined, num_bytes, num_handles)) =
18227 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18228 {
18229 let member_inline_size =
18230 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
18231 if inlined != (member_inline_size <= 4) {
18232 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18233 }
18234 let inner_offset;
18235 let mut inner_depth = depth.clone();
18236 if inlined {
18237 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18238 inner_offset = next_offset;
18239 } else {
18240 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18241 inner_depth.increment()?;
18242 }
18243 let val_ref = self.need_weak.get_or_insert_with(|| {
18244 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
18245 });
18246 fidl::decode!(
18247 bool,
18248 fidl::encoding::DefaultFuchsiaResourceDialect,
18249 val_ref,
18250 decoder,
18251 inner_offset,
18252 inner_depth
18253 )?;
18254 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18255 {
18256 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18257 }
18258 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18259 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18260 }
18261 }
18262
18263 next_offset += envelope_size;
18264 _next_ordinal_to_read += 1;
18265 if next_offset >= end_offset {
18266 return Ok(());
18267 }
18268
18269 // Decode unknown envelopes for gaps in ordinals.
18270 while _next_ordinal_to_read < 3 {
18271 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18272 _next_ordinal_to_read += 1;
18273 next_offset += envelope_size;
18274 }
18275
18276 let next_out_of_line = decoder.next_out_of_line();
18277 let handles_before = decoder.remaining_handles();
18278 if let Some((inlined, num_bytes, num_handles)) =
18279 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18280 {
18281 let member_inline_size =
18282 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
18283 if inlined != (member_inline_size <= 4) {
18284 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18285 }
18286 let inner_offset;
18287 let mut inner_depth = depth.clone();
18288 if inlined {
18289 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18290 inner_offset = next_offset;
18291 } else {
18292 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18293 inner_depth.increment()?;
18294 }
18295 let val_ref = self.need_single_buffer_settings.get_or_insert_with(|| {
18296 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
18297 });
18298 fidl::decode!(
18299 bool,
18300 fidl::encoding::DefaultFuchsiaResourceDialect,
18301 val_ref,
18302 decoder,
18303 inner_offset,
18304 inner_depth
18305 )?;
18306 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18307 {
18308 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18309 }
18310 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18311 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18312 }
18313 }
18314
18315 next_offset += envelope_size;
18316 _next_ordinal_to_read += 1;
18317 if next_offset >= end_offset {
18318 return Ok(());
18319 }
18320
18321 // Decode unknown envelopes for gaps in ordinals.
18322 while _next_ordinal_to_read < 4 {
18323 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18324 _next_ordinal_to_read += 1;
18325 next_offset += envelope_size;
18326 }
18327
18328 let next_out_of_line = decoder.next_out_of_line();
18329 let handles_before = decoder.remaining_handles();
18330 if let Some((inlined, num_bytes, num_handles)) =
18331 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18332 {
18333 let member_inline_size =
18334 <BufferCollectionConstraints as fidl::encoding::TypeMarker>::inline_size(
18335 decoder.context,
18336 );
18337 if inlined != (member_inline_size <= 4) {
18338 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18339 }
18340 let inner_offset;
18341 let mut inner_depth = depth.clone();
18342 if inlined {
18343 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18344 inner_offset = next_offset;
18345 } else {
18346 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18347 inner_depth.increment()?;
18348 }
18349 let val_ref = self.constraints_to_check.get_or_insert_with(|| {
18350 fidl::new_empty!(
18351 BufferCollectionConstraints,
18352 fidl::encoding::DefaultFuchsiaResourceDialect
18353 )
18354 });
18355 fidl::decode!(
18356 BufferCollectionConstraints,
18357 fidl::encoding::DefaultFuchsiaResourceDialect,
18358 val_ref,
18359 decoder,
18360 inner_offset,
18361 inner_depth
18362 )?;
18363 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18364 {
18365 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18366 }
18367 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18368 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18369 }
18370 }
18371
18372 next_offset += envelope_size;
18373 _next_ordinal_to_read += 1;
18374 if next_offset >= end_offset {
18375 return Ok(());
18376 }
18377
18378 // Decode unknown envelopes for gaps in ordinals.
18379 while _next_ordinal_to_read < 5 {
18380 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18381 _next_ordinal_to_read += 1;
18382 next_offset += envelope_size;
18383 }
18384
18385 let next_out_of_line = decoder.next_out_of_line();
18386 let handles_before = decoder.remaining_handles();
18387 if let Some((inlined, num_bytes, num_handles)) =
18388 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18389 {
18390 let member_inline_size = <fidl::encoding::HandleType<
18391 fidl::Vmo,
18392 { fidl::ObjectType::VMO.into_raw() },
18393 2147483648,
18394 > as fidl::encoding::TypeMarker>::inline_size(
18395 decoder.context
18396 );
18397 if inlined != (member_inline_size <= 4) {
18398 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18399 }
18400 let inner_offset;
18401 let mut inner_depth = depth.clone();
18402 if inlined {
18403 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18404 inner_offset = next_offset;
18405 } else {
18406 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18407 inner_depth.increment()?;
18408 }
18409 let val_ref =
18410 self.vmo_settings_to_check.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
18411 fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
18412 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18413 {
18414 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18415 }
18416 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18417 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18418 }
18419 }
18420
18421 next_offset += envelope_size;
18422 _next_ordinal_to_read += 1;
18423 if next_offset >= end_offset {
18424 return Ok(());
18425 }
18426
18427 // Decode unknown envelopes for gaps in ordinals.
18428 while _next_ordinal_to_read < 6 {
18429 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18430 _next_ordinal_to_read += 1;
18431 next_offset += envelope_size;
18432 }
18433
18434 let next_out_of_line = decoder.next_out_of_line();
18435 let handles_before = decoder.remaining_handles();
18436 if let Some((inlined, num_bytes, num_handles)) =
18437 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18438 {
18439 let member_inline_size =
18440 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
18441 if inlined != (member_inline_size <= 4) {
18442 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18443 }
18444 let inner_offset;
18445 let mut inner_depth = depth.clone();
18446 if inlined {
18447 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18448 inner_offset = next_offset;
18449 } else {
18450 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18451 inner_depth.increment()?;
18452 }
18453 let val_ref = self.vmo_settings_to_check_ignore_size.get_or_insert_with(|| {
18454 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
18455 });
18456 fidl::decode!(
18457 bool,
18458 fidl::encoding::DefaultFuchsiaResourceDialect,
18459 val_ref,
18460 decoder,
18461 inner_offset,
18462 inner_depth
18463 )?;
18464 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18465 {
18466 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18467 }
18468 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18469 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18470 }
18471 }
18472
18473 next_offset += envelope_size;
18474
18475 // Decode the remaining unknown envelopes.
18476 while next_offset < end_offset {
18477 _next_ordinal_to_read += 1;
18478 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18479 next_offset += envelope_size;
18480 }
18481
18482 Ok(())
18483 }
18484 }
18485
18486 impl AllocatorGetVmoInfoResponse {
18487 #[inline(always)]
18488 fn max_ordinal_present(&self) -> u64 {
18489 if let Some(_) = self.vmo_settings_match {
18490 return 7;
18491 }
18492 if let Some(_) = self.constraints_ok {
18493 return 6;
18494 }
18495 if let Some(_) = self.single_buffer_settings {
18496 return 5;
18497 }
18498 if let Some(_) = self.weak_vmo {
18499 return 4;
18500 }
18501 if let Some(_) = self.close_weak_asap {
18502 return 3;
18503 }
18504 if let Some(_) = self.buffer_index {
18505 return 2;
18506 }
18507 if let Some(_) = self.buffer_collection_id {
18508 return 1;
18509 }
18510 0
18511 }
18512 }
18513
18514 impl fidl::encoding::ResourceTypeMarker for AllocatorGetVmoInfoResponse {
18515 type Borrowed<'a> = &'a mut Self;
18516 fn take_or_borrow<'a>(
18517 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
18518 ) -> Self::Borrowed<'a> {
18519 value
18520 }
18521 }
18522
18523 unsafe impl fidl::encoding::TypeMarker for AllocatorGetVmoInfoResponse {
18524 type Owned = Self;
18525
18526 #[inline(always)]
18527 fn inline_align(_context: fidl::encoding::Context) -> usize {
18528 8
18529 }
18530
18531 #[inline(always)]
18532 fn inline_size(_context: fidl::encoding::Context) -> usize {
18533 16
18534 }
18535 }
18536
18537 unsafe impl
18538 fidl::encoding::Encode<
18539 AllocatorGetVmoInfoResponse,
18540 fidl::encoding::DefaultFuchsiaResourceDialect,
18541 > for &mut AllocatorGetVmoInfoResponse
18542 {
18543 unsafe fn encode(
18544 self,
18545 encoder: &mut fidl::encoding::Encoder<
18546 '_,
18547 fidl::encoding::DefaultFuchsiaResourceDialect,
18548 >,
18549 offset: usize,
18550 mut depth: fidl::encoding::Depth,
18551 ) -> fidl::Result<()> {
18552 encoder.debug_check_bounds::<AllocatorGetVmoInfoResponse>(offset);
18553 // Vector header
18554 let max_ordinal: u64 = self.max_ordinal_present();
18555 encoder.write_num(max_ordinal, offset);
18556 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
18557 // Calling encoder.out_of_line_offset(0) is not allowed.
18558 if max_ordinal == 0 {
18559 return Ok(());
18560 }
18561 depth.increment()?;
18562 let envelope_size = 8;
18563 let bytes_len = max_ordinal as usize * envelope_size;
18564 #[allow(unused_variables)]
18565 let offset = encoder.out_of_line_offset(bytes_len);
18566 let mut _prev_end_offset: usize = 0;
18567 if 1 > max_ordinal {
18568 return Ok(());
18569 }
18570
18571 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18572 // are envelope_size bytes.
18573 let cur_offset: usize = (1 - 1) * envelope_size;
18574
18575 // Zero reserved fields.
18576 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18577
18578 // Safety:
18579 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18580 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18581 // envelope_size bytes, there is always sufficient room.
18582 fidl::encoding::encode_in_envelope_optional::<
18583 u64,
18584 fidl::encoding::DefaultFuchsiaResourceDialect,
18585 >(
18586 self.buffer_collection_id
18587 .as_ref()
18588 .map(<u64 as fidl::encoding::ValueTypeMarker>::borrow),
18589 encoder,
18590 offset + cur_offset,
18591 depth,
18592 )?;
18593
18594 _prev_end_offset = cur_offset + envelope_size;
18595 if 2 > max_ordinal {
18596 return Ok(());
18597 }
18598
18599 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18600 // are envelope_size bytes.
18601 let cur_offset: usize = (2 - 1) * envelope_size;
18602
18603 // Zero reserved fields.
18604 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18605
18606 // Safety:
18607 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18608 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18609 // envelope_size bytes, there is always sufficient room.
18610 fidl::encoding::encode_in_envelope_optional::<
18611 u64,
18612 fidl::encoding::DefaultFuchsiaResourceDialect,
18613 >(
18614 self.buffer_index.as_ref().map(<u64 as fidl::encoding::ValueTypeMarker>::borrow),
18615 encoder,
18616 offset + cur_offset,
18617 depth,
18618 )?;
18619
18620 _prev_end_offset = cur_offset + envelope_size;
18621 if 3 > max_ordinal {
18622 return Ok(());
18623 }
18624
18625 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18626 // are envelope_size bytes.
18627 let cur_offset: usize = (3 - 1) * envelope_size;
18628
18629 // Zero reserved fields.
18630 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18631
18632 // Safety:
18633 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18634 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18635 // envelope_size bytes, there is always sufficient room.
18636 fidl::encoding::encode_in_envelope_optional::<
18637 fidl::encoding::HandleType<
18638 fidl::EventPair,
18639 { fidl::ObjectType::EVENTPAIR.into_raw() },
18640 2147483648,
18641 >,
18642 fidl::encoding::DefaultFuchsiaResourceDialect,
18643 >(
18644 self.close_weak_asap.as_mut().map(
18645 <fidl::encoding::HandleType<
18646 fidl::EventPair,
18647 { fidl::ObjectType::EVENTPAIR.into_raw() },
18648 2147483648,
18649 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
18650 ),
18651 encoder,
18652 offset + cur_offset,
18653 depth,
18654 )?;
18655
18656 _prev_end_offset = cur_offset + envelope_size;
18657 if 4 > max_ordinal {
18658 return Ok(());
18659 }
18660
18661 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18662 // are envelope_size bytes.
18663 let cur_offset: usize = (4 - 1) * envelope_size;
18664
18665 // Zero reserved fields.
18666 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18667
18668 // Safety:
18669 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18670 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18671 // envelope_size bytes, there is always sufficient room.
18672 fidl::encoding::encode_in_envelope_optional::<
18673 fidl::encoding::HandleType<
18674 fidl::Vmo,
18675 { fidl::ObjectType::VMO.into_raw() },
18676 2147483648,
18677 >,
18678 fidl::encoding::DefaultFuchsiaResourceDialect,
18679 >(
18680 self.weak_vmo.as_mut().map(
18681 <fidl::encoding::HandleType<
18682 fidl::Vmo,
18683 { fidl::ObjectType::VMO.into_raw() },
18684 2147483648,
18685 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
18686 ),
18687 encoder,
18688 offset + cur_offset,
18689 depth,
18690 )?;
18691
18692 _prev_end_offset = cur_offset + envelope_size;
18693 if 5 > max_ordinal {
18694 return Ok(());
18695 }
18696
18697 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18698 // are envelope_size bytes.
18699 let cur_offset: usize = (5 - 1) * envelope_size;
18700
18701 // Zero reserved fields.
18702 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18703
18704 // Safety:
18705 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18706 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18707 // envelope_size bytes, there is always sufficient room.
18708 fidl::encoding::encode_in_envelope_optional::<
18709 SingleBufferSettings,
18710 fidl::encoding::DefaultFuchsiaResourceDialect,
18711 >(
18712 self.single_buffer_settings
18713 .as_ref()
18714 .map(<SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow),
18715 encoder,
18716 offset + cur_offset,
18717 depth,
18718 )?;
18719
18720 _prev_end_offset = cur_offset + envelope_size;
18721 if 6 > max_ordinal {
18722 return Ok(());
18723 }
18724
18725 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18726 // are envelope_size bytes.
18727 let cur_offset: usize = (6 - 1) * envelope_size;
18728
18729 // Zero reserved fields.
18730 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18731
18732 // Safety:
18733 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18734 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18735 // envelope_size bytes, there is always sufficient room.
18736 fidl::encoding::encode_in_envelope_optional::<
18737 bool,
18738 fidl::encoding::DefaultFuchsiaResourceDialect,
18739 >(
18740 self.constraints_ok.as_ref().map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
18741 encoder,
18742 offset + cur_offset,
18743 depth,
18744 )?;
18745
18746 _prev_end_offset = cur_offset + envelope_size;
18747 if 7 > max_ordinal {
18748 return Ok(());
18749 }
18750
18751 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18752 // are envelope_size bytes.
18753 let cur_offset: usize = (7 - 1) * envelope_size;
18754
18755 // Zero reserved fields.
18756 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18757
18758 // Safety:
18759 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18760 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18761 // envelope_size bytes, there is always sufficient room.
18762 fidl::encoding::encode_in_envelope_optional::<
18763 bool,
18764 fidl::encoding::DefaultFuchsiaResourceDialect,
18765 >(
18766 self.vmo_settings_match
18767 .as_ref()
18768 .map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
18769 encoder,
18770 offset + cur_offset,
18771 depth,
18772 )?;
18773
18774 _prev_end_offset = cur_offset + envelope_size;
18775
18776 Ok(())
18777 }
18778 }
18779
18780 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
18781 for AllocatorGetVmoInfoResponse
18782 {
18783 #[inline(always)]
18784 fn new_empty() -> Self {
18785 Self::default()
18786 }
18787
18788 unsafe fn decode(
18789 &mut self,
18790 decoder: &mut fidl::encoding::Decoder<
18791 '_,
18792 fidl::encoding::DefaultFuchsiaResourceDialect,
18793 >,
18794 offset: usize,
18795 mut depth: fidl::encoding::Depth,
18796 ) -> fidl::Result<()> {
18797 decoder.debug_check_bounds::<Self>(offset);
18798 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
18799 None => return Err(fidl::Error::NotNullable),
18800 Some(len) => len,
18801 };
18802 // Calling decoder.out_of_line_offset(0) is not allowed.
18803 if len == 0 {
18804 return Ok(());
18805 };
18806 depth.increment()?;
18807 let envelope_size = 8;
18808 let bytes_len = len * envelope_size;
18809 let offset = decoder.out_of_line_offset(bytes_len)?;
18810 // Decode the envelope for each type.
18811 let mut _next_ordinal_to_read = 0;
18812 let mut next_offset = offset;
18813 let end_offset = offset + bytes_len;
18814 _next_ordinal_to_read += 1;
18815 if next_offset >= end_offset {
18816 return Ok(());
18817 }
18818
18819 // Decode unknown envelopes for gaps in ordinals.
18820 while _next_ordinal_to_read < 1 {
18821 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18822 _next_ordinal_to_read += 1;
18823 next_offset += envelope_size;
18824 }
18825
18826 let next_out_of_line = decoder.next_out_of_line();
18827 let handles_before = decoder.remaining_handles();
18828 if let Some((inlined, num_bytes, num_handles)) =
18829 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18830 {
18831 let member_inline_size =
18832 <u64 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
18833 if inlined != (member_inline_size <= 4) {
18834 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18835 }
18836 let inner_offset;
18837 let mut inner_depth = depth.clone();
18838 if inlined {
18839 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18840 inner_offset = next_offset;
18841 } else {
18842 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18843 inner_depth.increment()?;
18844 }
18845 let val_ref = self.buffer_collection_id.get_or_insert_with(|| {
18846 fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect)
18847 });
18848 fidl::decode!(
18849 u64,
18850 fidl::encoding::DefaultFuchsiaResourceDialect,
18851 val_ref,
18852 decoder,
18853 inner_offset,
18854 inner_depth
18855 )?;
18856 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18857 {
18858 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18859 }
18860 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18861 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18862 }
18863 }
18864
18865 next_offset += envelope_size;
18866 _next_ordinal_to_read += 1;
18867 if next_offset >= end_offset {
18868 return Ok(());
18869 }
18870
18871 // Decode unknown envelopes for gaps in ordinals.
18872 while _next_ordinal_to_read < 2 {
18873 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18874 _next_ordinal_to_read += 1;
18875 next_offset += envelope_size;
18876 }
18877
18878 let next_out_of_line = decoder.next_out_of_line();
18879 let handles_before = decoder.remaining_handles();
18880 if let Some((inlined, num_bytes, num_handles)) =
18881 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18882 {
18883 let member_inline_size =
18884 <u64 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
18885 if inlined != (member_inline_size <= 4) {
18886 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18887 }
18888 let inner_offset;
18889 let mut inner_depth = depth.clone();
18890 if inlined {
18891 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18892 inner_offset = next_offset;
18893 } else {
18894 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18895 inner_depth.increment()?;
18896 }
18897 let val_ref = self.buffer_index.get_or_insert_with(|| {
18898 fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect)
18899 });
18900 fidl::decode!(
18901 u64,
18902 fidl::encoding::DefaultFuchsiaResourceDialect,
18903 val_ref,
18904 decoder,
18905 inner_offset,
18906 inner_depth
18907 )?;
18908 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18909 {
18910 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18911 }
18912 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18913 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18914 }
18915 }
18916
18917 next_offset += envelope_size;
18918 _next_ordinal_to_read += 1;
18919 if next_offset >= end_offset {
18920 return Ok(());
18921 }
18922
18923 // Decode unknown envelopes for gaps in ordinals.
18924 while _next_ordinal_to_read < 3 {
18925 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18926 _next_ordinal_to_read += 1;
18927 next_offset += envelope_size;
18928 }
18929
18930 let next_out_of_line = decoder.next_out_of_line();
18931 let handles_before = decoder.remaining_handles();
18932 if let Some((inlined, num_bytes, num_handles)) =
18933 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18934 {
18935 let member_inline_size = <fidl::encoding::HandleType<
18936 fidl::EventPair,
18937 { fidl::ObjectType::EVENTPAIR.into_raw() },
18938 2147483648,
18939 > as fidl::encoding::TypeMarker>::inline_size(
18940 decoder.context
18941 );
18942 if inlined != (member_inline_size <= 4) {
18943 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18944 }
18945 let inner_offset;
18946 let mut inner_depth = depth.clone();
18947 if inlined {
18948 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18949 inner_offset = next_offset;
18950 } else {
18951 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18952 inner_depth.increment()?;
18953 }
18954 let val_ref =
18955 self.close_weak_asap.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
18956 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
18957 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18958 {
18959 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18960 }
18961 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18962 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18963 }
18964 }
18965
18966 next_offset += envelope_size;
18967 _next_ordinal_to_read += 1;
18968 if next_offset >= end_offset {
18969 return Ok(());
18970 }
18971
18972 // Decode unknown envelopes for gaps in ordinals.
18973 while _next_ordinal_to_read < 4 {
18974 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18975 _next_ordinal_to_read += 1;
18976 next_offset += envelope_size;
18977 }
18978
18979 let next_out_of_line = decoder.next_out_of_line();
18980 let handles_before = decoder.remaining_handles();
18981 if let Some((inlined, num_bytes, num_handles)) =
18982 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18983 {
18984 let member_inline_size = <fidl::encoding::HandleType<
18985 fidl::Vmo,
18986 { fidl::ObjectType::VMO.into_raw() },
18987 2147483648,
18988 > as fidl::encoding::TypeMarker>::inline_size(
18989 decoder.context
18990 );
18991 if inlined != (member_inline_size <= 4) {
18992 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18993 }
18994 let inner_offset;
18995 let mut inner_depth = depth.clone();
18996 if inlined {
18997 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18998 inner_offset = next_offset;
18999 } else {
19000 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19001 inner_depth.increment()?;
19002 }
19003 let val_ref =
19004 self.weak_vmo.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
19005 fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
19006 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19007 {
19008 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19009 }
19010 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19011 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19012 }
19013 }
19014
19015 next_offset += envelope_size;
19016 _next_ordinal_to_read += 1;
19017 if next_offset >= end_offset {
19018 return Ok(());
19019 }
19020
19021 // Decode unknown envelopes for gaps in ordinals.
19022 while _next_ordinal_to_read < 5 {
19023 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19024 _next_ordinal_to_read += 1;
19025 next_offset += envelope_size;
19026 }
19027
19028 let next_out_of_line = decoder.next_out_of_line();
19029 let handles_before = decoder.remaining_handles();
19030 if let Some((inlined, num_bytes, num_handles)) =
19031 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19032 {
19033 let member_inline_size =
19034 <SingleBufferSettings as fidl::encoding::TypeMarker>::inline_size(
19035 decoder.context,
19036 );
19037 if inlined != (member_inline_size <= 4) {
19038 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19039 }
19040 let inner_offset;
19041 let mut inner_depth = depth.clone();
19042 if inlined {
19043 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19044 inner_offset = next_offset;
19045 } else {
19046 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19047 inner_depth.increment()?;
19048 }
19049 let val_ref = self.single_buffer_settings.get_or_insert_with(|| {
19050 fidl::new_empty!(
19051 SingleBufferSettings,
19052 fidl::encoding::DefaultFuchsiaResourceDialect
19053 )
19054 });
19055 fidl::decode!(
19056 SingleBufferSettings,
19057 fidl::encoding::DefaultFuchsiaResourceDialect,
19058 val_ref,
19059 decoder,
19060 inner_offset,
19061 inner_depth
19062 )?;
19063 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19064 {
19065 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19066 }
19067 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19068 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19069 }
19070 }
19071
19072 next_offset += envelope_size;
19073 _next_ordinal_to_read += 1;
19074 if next_offset >= end_offset {
19075 return Ok(());
19076 }
19077
19078 // Decode unknown envelopes for gaps in ordinals.
19079 while _next_ordinal_to_read < 6 {
19080 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19081 _next_ordinal_to_read += 1;
19082 next_offset += envelope_size;
19083 }
19084
19085 let next_out_of_line = decoder.next_out_of_line();
19086 let handles_before = decoder.remaining_handles();
19087 if let Some((inlined, num_bytes, num_handles)) =
19088 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19089 {
19090 let member_inline_size =
19091 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
19092 if inlined != (member_inline_size <= 4) {
19093 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19094 }
19095 let inner_offset;
19096 let mut inner_depth = depth.clone();
19097 if inlined {
19098 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19099 inner_offset = next_offset;
19100 } else {
19101 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19102 inner_depth.increment()?;
19103 }
19104 let val_ref = self.constraints_ok.get_or_insert_with(|| {
19105 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
19106 });
19107 fidl::decode!(
19108 bool,
19109 fidl::encoding::DefaultFuchsiaResourceDialect,
19110 val_ref,
19111 decoder,
19112 inner_offset,
19113 inner_depth
19114 )?;
19115 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19116 {
19117 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19118 }
19119 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19120 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19121 }
19122 }
19123
19124 next_offset += envelope_size;
19125 _next_ordinal_to_read += 1;
19126 if next_offset >= end_offset {
19127 return Ok(());
19128 }
19129
19130 // Decode unknown envelopes for gaps in ordinals.
19131 while _next_ordinal_to_read < 7 {
19132 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19133 _next_ordinal_to_read += 1;
19134 next_offset += envelope_size;
19135 }
19136
19137 let next_out_of_line = decoder.next_out_of_line();
19138 let handles_before = decoder.remaining_handles();
19139 if let Some((inlined, num_bytes, num_handles)) =
19140 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19141 {
19142 let member_inline_size =
19143 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
19144 if inlined != (member_inline_size <= 4) {
19145 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19146 }
19147 let inner_offset;
19148 let mut inner_depth = depth.clone();
19149 if inlined {
19150 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19151 inner_offset = next_offset;
19152 } else {
19153 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19154 inner_depth.increment()?;
19155 }
19156 let val_ref = self.vmo_settings_match.get_or_insert_with(|| {
19157 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
19158 });
19159 fidl::decode!(
19160 bool,
19161 fidl::encoding::DefaultFuchsiaResourceDialect,
19162 val_ref,
19163 decoder,
19164 inner_offset,
19165 inner_depth
19166 )?;
19167 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19168 {
19169 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19170 }
19171 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19172 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19173 }
19174 }
19175
19176 next_offset += envelope_size;
19177
19178 // Decode the remaining unknown envelopes.
19179 while next_offset < end_offset {
19180 _next_ordinal_to_read += 1;
19181 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19182 next_offset += envelope_size;
19183 }
19184
19185 Ok(())
19186 }
19187 }
19188
19189 impl BufferCollectionAttachLifetimeTrackingRequest {
19190 #[inline(always)]
19191 fn max_ordinal_present(&self) -> u64 {
19192 if let Some(_) = self.buffers_remaining {
19193 return 2;
19194 }
19195 if let Some(_) = self.server_end {
19196 return 1;
19197 }
19198 0
19199 }
19200 }
19201
19202 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
19203 type Borrowed<'a> = &'a mut Self;
19204 fn take_or_borrow<'a>(
19205 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
19206 ) -> Self::Borrowed<'a> {
19207 value
19208 }
19209 }
19210
19211 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
19212 type Owned = Self;
19213
19214 #[inline(always)]
19215 fn inline_align(_context: fidl::encoding::Context) -> usize {
19216 8
19217 }
19218
19219 #[inline(always)]
19220 fn inline_size(_context: fidl::encoding::Context) -> usize {
19221 16
19222 }
19223 }
19224
19225 unsafe impl
19226 fidl::encoding::Encode<
19227 BufferCollectionAttachLifetimeTrackingRequest,
19228 fidl::encoding::DefaultFuchsiaResourceDialect,
19229 > for &mut BufferCollectionAttachLifetimeTrackingRequest
19230 {
19231 unsafe fn encode(
19232 self,
19233 encoder: &mut fidl::encoding::Encoder<
19234 '_,
19235 fidl::encoding::DefaultFuchsiaResourceDialect,
19236 >,
19237 offset: usize,
19238 mut depth: fidl::encoding::Depth,
19239 ) -> fidl::Result<()> {
19240 encoder.debug_check_bounds::<BufferCollectionAttachLifetimeTrackingRequest>(offset);
19241 // Vector header
19242 let max_ordinal: u64 = self.max_ordinal_present();
19243 encoder.write_num(max_ordinal, offset);
19244 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
19245 // Calling encoder.out_of_line_offset(0) is not allowed.
19246 if max_ordinal == 0 {
19247 return Ok(());
19248 }
19249 depth.increment()?;
19250 let envelope_size = 8;
19251 let bytes_len = max_ordinal as usize * envelope_size;
19252 #[allow(unused_variables)]
19253 let offset = encoder.out_of_line_offset(bytes_len);
19254 let mut _prev_end_offset: usize = 0;
19255 if 1 > max_ordinal {
19256 return Ok(());
19257 }
19258
19259 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19260 // are envelope_size bytes.
19261 let cur_offset: usize = (1 - 1) * envelope_size;
19262
19263 // Zero reserved fields.
19264 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19265
19266 // Safety:
19267 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19268 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19269 // envelope_size bytes, there is always sufficient room.
19270 fidl::encoding::encode_in_envelope_optional::<
19271 fidl::encoding::HandleType<
19272 fidl::EventPair,
19273 { fidl::ObjectType::EVENTPAIR.into_raw() },
19274 2147483648,
19275 >,
19276 fidl::encoding::DefaultFuchsiaResourceDialect,
19277 >(
19278 self.server_end.as_mut().map(
19279 <fidl::encoding::HandleType<
19280 fidl::EventPair,
19281 { fidl::ObjectType::EVENTPAIR.into_raw() },
19282 2147483648,
19283 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
19284 ),
19285 encoder,
19286 offset + cur_offset,
19287 depth,
19288 )?;
19289
19290 _prev_end_offset = cur_offset + envelope_size;
19291 if 2 > max_ordinal {
19292 return Ok(());
19293 }
19294
19295 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19296 // are envelope_size bytes.
19297 let cur_offset: usize = (2 - 1) * envelope_size;
19298
19299 // Zero reserved fields.
19300 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19301
19302 // Safety:
19303 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19304 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19305 // envelope_size bytes, there is always sufficient room.
19306 fidl::encoding::encode_in_envelope_optional::<
19307 u32,
19308 fidl::encoding::DefaultFuchsiaResourceDialect,
19309 >(
19310 self.buffers_remaining
19311 .as_ref()
19312 .map(<u32 as fidl::encoding::ValueTypeMarker>::borrow),
19313 encoder,
19314 offset + cur_offset,
19315 depth,
19316 )?;
19317
19318 _prev_end_offset = cur_offset + envelope_size;
19319
19320 Ok(())
19321 }
19322 }
19323
19324 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
19325 for BufferCollectionAttachLifetimeTrackingRequest
19326 {
19327 #[inline(always)]
19328 fn new_empty() -> Self {
19329 Self::default()
19330 }
19331
19332 unsafe fn decode(
19333 &mut self,
19334 decoder: &mut fidl::encoding::Decoder<
19335 '_,
19336 fidl::encoding::DefaultFuchsiaResourceDialect,
19337 >,
19338 offset: usize,
19339 mut depth: fidl::encoding::Depth,
19340 ) -> fidl::Result<()> {
19341 decoder.debug_check_bounds::<Self>(offset);
19342 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
19343 None => return Err(fidl::Error::NotNullable),
19344 Some(len) => len,
19345 };
19346 // Calling decoder.out_of_line_offset(0) is not allowed.
19347 if len == 0 {
19348 return Ok(());
19349 };
19350 depth.increment()?;
19351 let envelope_size = 8;
19352 let bytes_len = len * envelope_size;
19353 let offset = decoder.out_of_line_offset(bytes_len)?;
19354 // Decode the envelope for each type.
19355 let mut _next_ordinal_to_read = 0;
19356 let mut next_offset = offset;
19357 let end_offset = offset + bytes_len;
19358 _next_ordinal_to_read += 1;
19359 if next_offset >= end_offset {
19360 return Ok(());
19361 }
19362
19363 // Decode unknown envelopes for gaps in ordinals.
19364 while _next_ordinal_to_read < 1 {
19365 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19366 _next_ordinal_to_read += 1;
19367 next_offset += envelope_size;
19368 }
19369
19370 let next_out_of_line = decoder.next_out_of_line();
19371 let handles_before = decoder.remaining_handles();
19372 if let Some((inlined, num_bytes, num_handles)) =
19373 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19374 {
19375 let member_inline_size = <fidl::encoding::HandleType<
19376 fidl::EventPair,
19377 { fidl::ObjectType::EVENTPAIR.into_raw() },
19378 2147483648,
19379 > as fidl::encoding::TypeMarker>::inline_size(
19380 decoder.context
19381 );
19382 if inlined != (member_inline_size <= 4) {
19383 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19384 }
19385 let inner_offset;
19386 let mut inner_depth = depth.clone();
19387 if inlined {
19388 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19389 inner_offset = next_offset;
19390 } else {
19391 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19392 inner_depth.increment()?;
19393 }
19394 let val_ref =
19395 self.server_end.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
19396 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
19397 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19398 {
19399 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19400 }
19401 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19402 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19403 }
19404 }
19405
19406 next_offset += envelope_size;
19407 _next_ordinal_to_read += 1;
19408 if next_offset >= end_offset {
19409 return Ok(());
19410 }
19411
19412 // Decode unknown envelopes for gaps in ordinals.
19413 while _next_ordinal_to_read < 2 {
19414 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19415 _next_ordinal_to_read += 1;
19416 next_offset += envelope_size;
19417 }
19418
19419 let next_out_of_line = decoder.next_out_of_line();
19420 let handles_before = decoder.remaining_handles();
19421 if let Some((inlined, num_bytes, num_handles)) =
19422 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19423 {
19424 let member_inline_size =
19425 <u32 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
19426 if inlined != (member_inline_size <= 4) {
19427 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19428 }
19429 let inner_offset;
19430 let mut inner_depth = depth.clone();
19431 if inlined {
19432 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19433 inner_offset = next_offset;
19434 } else {
19435 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19436 inner_depth.increment()?;
19437 }
19438 let val_ref = self.buffers_remaining.get_or_insert_with(|| {
19439 fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect)
19440 });
19441 fidl::decode!(
19442 u32,
19443 fidl::encoding::DefaultFuchsiaResourceDialect,
19444 val_ref,
19445 decoder,
19446 inner_offset,
19447 inner_depth
19448 )?;
19449 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19450 {
19451 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19452 }
19453 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19454 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19455 }
19456 }
19457
19458 next_offset += envelope_size;
19459
19460 // Decode the remaining unknown envelopes.
19461 while next_offset < end_offset {
19462 _next_ordinal_to_read += 1;
19463 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19464 next_offset += envelope_size;
19465 }
19466
19467 Ok(())
19468 }
19469 }
19470
19471 impl BufferCollectionAttachTokenRequest {
19472 #[inline(always)]
19473 fn max_ordinal_present(&self) -> u64 {
19474 if let Some(_) = self.token_request {
19475 return 2;
19476 }
19477 if let Some(_) = self.rights_attenuation_mask {
19478 return 1;
19479 }
19480 0
19481 }
19482 }
19483
19484 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachTokenRequest {
19485 type Borrowed<'a> = &'a mut Self;
19486 fn take_or_borrow<'a>(
19487 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
19488 ) -> Self::Borrowed<'a> {
19489 value
19490 }
19491 }
19492
19493 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachTokenRequest {
19494 type Owned = Self;
19495
19496 #[inline(always)]
19497 fn inline_align(_context: fidl::encoding::Context) -> usize {
19498 8
19499 }
19500
19501 #[inline(always)]
19502 fn inline_size(_context: fidl::encoding::Context) -> usize {
19503 16
19504 }
19505 }
19506
19507 unsafe impl
19508 fidl::encoding::Encode<
19509 BufferCollectionAttachTokenRequest,
19510 fidl::encoding::DefaultFuchsiaResourceDialect,
19511 > for &mut BufferCollectionAttachTokenRequest
19512 {
19513 unsafe fn encode(
19514 self,
19515 encoder: &mut fidl::encoding::Encoder<
19516 '_,
19517 fidl::encoding::DefaultFuchsiaResourceDialect,
19518 >,
19519 offset: usize,
19520 mut depth: fidl::encoding::Depth,
19521 ) -> fidl::Result<()> {
19522 encoder.debug_check_bounds::<BufferCollectionAttachTokenRequest>(offset);
19523 // Vector header
19524 let max_ordinal: u64 = self.max_ordinal_present();
19525 encoder.write_num(max_ordinal, offset);
19526 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
19527 // Calling encoder.out_of_line_offset(0) is not allowed.
19528 if max_ordinal == 0 {
19529 return Ok(());
19530 }
19531 depth.increment()?;
19532 let envelope_size = 8;
19533 let bytes_len = max_ordinal as usize * envelope_size;
19534 #[allow(unused_variables)]
19535 let offset = encoder.out_of_line_offset(bytes_len);
19536 let mut _prev_end_offset: usize = 0;
19537 if 1 > max_ordinal {
19538 return Ok(());
19539 }
19540
19541 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19542 // are envelope_size bytes.
19543 let cur_offset: usize = (1 - 1) * envelope_size;
19544
19545 // Zero reserved fields.
19546 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19547
19548 // Safety:
19549 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19550 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19551 // envelope_size bytes, there is always sufficient room.
19552 fidl::encoding::encode_in_envelope_optional::<
19553 fidl::Rights,
19554 fidl::encoding::DefaultFuchsiaResourceDialect,
19555 >(
19556 self.rights_attenuation_mask
19557 .as_ref()
19558 .map(<fidl::Rights as fidl::encoding::ValueTypeMarker>::borrow),
19559 encoder,
19560 offset + cur_offset,
19561 depth,
19562 )?;
19563
19564 _prev_end_offset = cur_offset + envelope_size;
19565 if 2 > max_ordinal {
19566 return Ok(());
19567 }
19568
19569 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19570 // are envelope_size bytes.
19571 let cur_offset: usize = (2 - 1) * envelope_size;
19572
19573 // Zero reserved fields.
19574 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19575
19576 // Safety:
19577 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19578 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19579 // envelope_size bytes, there is always sufficient room.
19580 fidl::encoding::encode_in_envelope_optional::<
19581 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
19582 fidl::encoding::DefaultFuchsiaResourceDialect,
19583 >(
19584 self.token_request.as_mut().map(
19585 <fidl::encoding::Endpoint<
19586 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
19587 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
19588 ),
19589 encoder,
19590 offset + cur_offset,
19591 depth,
19592 )?;
19593
19594 _prev_end_offset = cur_offset + envelope_size;
19595
19596 Ok(())
19597 }
19598 }
19599
19600 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
19601 for BufferCollectionAttachTokenRequest
19602 {
19603 #[inline(always)]
19604 fn new_empty() -> Self {
19605 Self::default()
19606 }
19607
19608 unsafe fn decode(
19609 &mut self,
19610 decoder: &mut fidl::encoding::Decoder<
19611 '_,
19612 fidl::encoding::DefaultFuchsiaResourceDialect,
19613 >,
19614 offset: usize,
19615 mut depth: fidl::encoding::Depth,
19616 ) -> fidl::Result<()> {
19617 decoder.debug_check_bounds::<Self>(offset);
19618 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
19619 None => return Err(fidl::Error::NotNullable),
19620 Some(len) => len,
19621 };
19622 // Calling decoder.out_of_line_offset(0) is not allowed.
19623 if len == 0 {
19624 return Ok(());
19625 };
19626 depth.increment()?;
19627 let envelope_size = 8;
19628 let bytes_len = len * envelope_size;
19629 let offset = decoder.out_of_line_offset(bytes_len)?;
19630 // Decode the envelope for each type.
19631 let mut _next_ordinal_to_read = 0;
19632 let mut next_offset = offset;
19633 let end_offset = offset + bytes_len;
19634 _next_ordinal_to_read += 1;
19635 if next_offset >= end_offset {
19636 return Ok(());
19637 }
19638
19639 // Decode unknown envelopes for gaps in ordinals.
19640 while _next_ordinal_to_read < 1 {
19641 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19642 _next_ordinal_to_read += 1;
19643 next_offset += envelope_size;
19644 }
19645
19646 let next_out_of_line = decoder.next_out_of_line();
19647 let handles_before = decoder.remaining_handles();
19648 if let Some((inlined, num_bytes, num_handles)) =
19649 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19650 {
19651 let member_inline_size =
19652 <fidl::Rights as fidl::encoding::TypeMarker>::inline_size(decoder.context);
19653 if inlined != (member_inline_size <= 4) {
19654 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19655 }
19656 let inner_offset;
19657 let mut inner_depth = depth.clone();
19658 if inlined {
19659 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19660 inner_offset = next_offset;
19661 } else {
19662 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19663 inner_depth.increment()?;
19664 }
19665 let val_ref = self.rights_attenuation_mask.get_or_insert_with(|| {
19666 fidl::new_empty!(fidl::Rights, fidl::encoding::DefaultFuchsiaResourceDialect)
19667 });
19668 fidl::decode!(
19669 fidl::Rights,
19670 fidl::encoding::DefaultFuchsiaResourceDialect,
19671 val_ref,
19672 decoder,
19673 inner_offset,
19674 inner_depth
19675 )?;
19676 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19677 {
19678 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19679 }
19680 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19681 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19682 }
19683 }
19684
19685 next_offset += envelope_size;
19686 _next_ordinal_to_read += 1;
19687 if next_offset >= end_offset {
19688 return Ok(());
19689 }
19690
19691 // Decode unknown envelopes for gaps in ordinals.
19692 while _next_ordinal_to_read < 2 {
19693 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19694 _next_ordinal_to_read += 1;
19695 next_offset += envelope_size;
19696 }
19697
19698 let next_out_of_line = decoder.next_out_of_line();
19699 let handles_before = decoder.remaining_handles();
19700 if let Some((inlined, num_bytes, num_handles)) =
19701 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19702 {
19703 let member_inline_size = <fidl::encoding::Endpoint<
19704 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
19705 > as fidl::encoding::TypeMarker>::inline_size(
19706 decoder.context
19707 );
19708 if inlined != (member_inline_size <= 4) {
19709 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19710 }
19711 let inner_offset;
19712 let mut inner_depth = depth.clone();
19713 if inlined {
19714 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19715 inner_offset = next_offset;
19716 } else {
19717 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19718 inner_depth.increment()?;
19719 }
19720 let val_ref = self.token_request.get_or_insert_with(|| {
19721 fidl::new_empty!(
19722 fidl::encoding::Endpoint<
19723 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
19724 >,
19725 fidl::encoding::DefaultFuchsiaResourceDialect
19726 )
19727 });
19728 fidl::decode!(
19729 fidl::encoding::Endpoint<
19730 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
19731 >,
19732 fidl::encoding::DefaultFuchsiaResourceDialect,
19733 val_ref,
19734 decoder,
19735 inner_offset,
19736 inner_depth
19737 )?;
19738 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19739 {
19740 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19741 }
19742 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19743 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19744 }
19745 }
19746
19747 next_offset += envelope_size;
19748
19749 // Decode the remaining unknown envelopes.
19750 while next_offset < end_offset {
19751 _next_ordinal_to_read += 1;
19752 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19753 next_offset += envelope_size;
19754 }
19755
19756 Ok(())
19757 }
19758 }
19759
19760 impl BufferCollectionInfo {
19761 #[inline(always)]
19762 fn max_ordinal_present(&self) -> u64 {
19763 if let Some(_) = self.buffer_collection_id {
19764 return 3;
19765 }
19766 if let Some(_) = self.buffers {
19767 return 2;
19768 }
19769 if let Some(_) = self.settings {
19770 return 1;
19771 }
19772 0
19773 }
19774 }
19775
19776 impl fidl::encoding::ResourceTypeMarker for BufferCollectionInfo {
19777 type Borrowed<'a> = &'a mut Self;
19778 fn take_or_borrow<'a>(
19779 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
19780 ) -> Self::Borrowed<'a> {
19781 value
19782 }
19783 }
19784
19785 unsafe impl fidl::encoding::TypeMarker for BufferCollectionInfo {
19786 type Owned = Self;
19787
19788 #[inline(always)]
19789 fn inline_align(_context: fidl::encoding::Context) -> usize {
19790 8
19791 }
19792
19793 #[inline(always)]
19794 fn inline_size(_context: fidl::encoding::Context) -> usize {
19795 16
19796 }
19797 }
19798
19799 unsafe impl
19800 fidl::encoding::Encode<BufferCollectionInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
19801 for &mut BufferCollectionInfo
19802 {
19803 unsafe fn encode(
19804 self,
19805 encoder: &mut fidl::encoding::Encoder<
19806 '_,
19807 fidl::encoding::DefaultFuchsiaResourceDialect,
19808 >,
19809 offset: usize,
19810 mut depth: fidl::encoding::Depth,
19811 ) -> fidl::Result<()> {
19812 encoder.debug_check_bounds::<BufferCollectionInfo>(offset);
19813 // Vector header
19814 let max_ordinal: u64 = self.max_ordinal_present();
19815 encoder.write_num(max_ordinal, offset);
19816 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
19817 // Calling encoder.out_of_line_offset(0) is not allowed.
19818 if max_ordinal == 0 {
19819 return Ok(());
19820 }
19821 depth.increment()?;
19822 let envelope_size = 8;
19823 let bytes_len = max_ordinal as usize * envelope_size;
19824 #[allow(unused_variables)]
19825 let offset = encoder.out_of_line_offset(bytes_len);
19826 let mut _prev_end_offset: usize = 0;
19827 if 1 > max_ordinal {
19828 return Ok(());
19829 }
19830
19831 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19832 // are envelope_size bytes.
19833 let cur_offset: usize = (1 - 1) * envelope_size;
19834
19835 // Zero reserved fields.
19836 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19837
19838 // Safety:
19839 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19840 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19841 // envelope_size bytes, there is always sufficient room.
19842 fidl::encoding::encode_in_envelope_optional::<
19843 SingleBufferSettings,
19844 fidl::encoding::DefaultFuchsiaResourceDialect,
19845 >(
19846 self.settings
19847 .as_ref()
19848 .map(<SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow),
19849 encoder,
19850 offset + cur_offset,
19851 depth,
19852 )?;
19853
19854 _prev_end_offset = cur_offset + envelope_size;
19855 if 2 > max_ordinal {
19856 return Ok(());
19857 }
19858
19859 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19860 // are envelope_size bytes.
19861 let cur_offset: usize = (2 - 1) * envelope_size;
19862
19863 // Zero reserved fields.
19864 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19865
19866 // Safety:
19867 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19868 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19869 // envelope_size bytes, there is always sufficient room.
19870 fidl::encoding::encode_in_envelope_optional::<fidl::encoding::Vector<VmoBuffer, 128>, fidl::encoding::DefaultFuchsiaResourceDialect>(
19871 self.buffers.as_mut().map(<fidl::encoding::Vector<VmoBuffer, 128> as fidl::encoding::ResourceTypeMarker>::take_or_borrow),
19872 encoder, offset + cur_offset, depth
19873 )?;
19874
19875 _prev_end_offset = cur_offset + envelope_size;
19876 if 3 > max_ordinal {
19877 return Ok(());
19878 }
19879
19880 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19881 // are envelope_size bytes.
19882 let cur_offset: usize = (3 - 1) * envelope_size;
19883
19884 // Zero reserved fields.
19885 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19886
19887 // Safety:
19888 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19889 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19890 // envelope_size bytes, there is always sufficient room.
19891 fidl::encoding::encode_in_envelope_optional::<
19892 u64,
19893 fidl::encoding::DefaultFuchsiaResourceDialect,
19894 >(
19895 self.buffer_collection_id
19896 .as_ref()
19897 .map(<u64 as fidl::encoding::ValueTypeMarker>::borrow),
19898 encoder,
19899 offset + cur_offset,
19900 depth,
19901 )?;
19902
19903 _prev_end_offset = cur_offset + envelope_size;
19904
19905 Ok(())
19906 }
19907 }
19908
19909 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
19910 for BufferCollectionInfo
19911 {
19912 #[inline(always)]
19913 fn new_empty() -> Self {
19914 Self::default()
19915 }
19916
19917 unsafe fn decode(
19918 &mut self,
19919 decoder: &mut fidl::encoding::Decoder<
19920 '_,
19921 fidl::encoding::DefaultFuchsiaResourceDialect,
19922 >,
19923 offset: usize,
19924 mut depth: fidl::encoding::Depth,
19925 ) -> fidl::Result<()> {
19926 decoder.debug_check_bounds::<Self>(offset);
19927 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
19928 None => return Err(fidl::Error::NotNullable),
19929 Some(len) => len,
19930 };
19931 // Calling decoder.out_of_line_offset(0) is not allowed.
19932 if len == 0 {
19933 return Ok(());
19934 };
19935 depth.increment()?;
19936 let envelope_size = 8;
19937 let bytes_len = len * envelope_size;
19938 let offset = decoder.out_of_line_offset(bytes_len)?;
19939 // Decode the envelope for each type.
19940 let mut _next_ordinal_to_read = 0;
19941 let mut next_offset = offset;
19942 let end_offset = offset + bytes_len;
19943 _next_ordinal_to_read += 1;
19944 if next_offset >= end_offset {
19945 return Ok(());
19946 }
19947
19948 // Decode unknown envelopes for gaps in ordinals.
19949 while _next_ordinal_to_read < 1 {
19950 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19951 _next_ordinal_to_read += 1;
19952 next_offset += envelope_size;
19953 }
19954
19955 let next_out_of_line = decoder.next_out_of_line();
19956 let handles_before = decoder.remaining_handles();
19957 if let Some((inlined, num_bytes, num_handles)) =
19958 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19959 {
19960 let member_inline_size =
19961 <SingleBufferSettings as fidl::encoding::TypeMarker>::inline_size(
19962 decoder.context,
19963 );
19964 if inlined != (member_inline_size <= 4) {
19965 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19966 }
19967 let inner_offset;
19968 let mut inner_depth = depth.clone();
19969 if inlined {
19970 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19971 inner_offset = next_offset;
19972 } else {
19973 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19974 inner_depth.increment()?;
19975 }
19976 let val_ref = self.settings.get_or_insert_with(|| {
19977 fidl::new_empty!(
19978 SingleBufferSettings,
19979 fidl::encoding::DefaultFuchsiaResourceDialect
19980 )
19981 });
19982 fidl::decode!(
19983 SingleBufferSettings,
19984 fidl::encoding::DefaultFuchsiaResourceDialect,
19985 val_ref,
19986 decoder,
19987 inner_offset,
19988 inner_depth
19989 )?;
19990 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19991 {
19992 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19993 }
19994 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19995 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19996 }
19997 }
19998
19999 next_offset += envelope_size;
20000 _next_ordinal_to_read += 1;
20001 if next_offset >= end_offset {
20002 return Ok(());
20003 }
20004
20005 // Decode unknown envelopes for gaps in ordinals.
20006 while _next_ordinal_to_read < 2 {
20007 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20008 _next_ordinal_to_read += 1;
20009 next_offset += envelope_size;
20010 }
20011
20012 let next_out_of_line = decoder.next_out_of_line();
20013 let handles_before = decoder.remaining_handles();
20014 if let Some((inlined, num_bytes, num_handles)) =
20015 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20016 {
20017 let member_inline_size = <fidl::encoding::Vector<VmoBuffer, 128> as fidl::encoding::TypeMarker>::inline_size(decoder.context);
20018 if inlined != (member_inline_size <= 4) {
20019 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20020 }
20021 let inner_offset;
20022 let mut inner_depth = depth.clone();
20023 if inlined {
20024 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20025 inner_offset = next_offset;
20026 } else {
20027 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20028 inner_depth.increment()?;
20029 }
20030 let val_ref =
20031 self.buffers.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::Vector<VmoBuffer, 128>, fidl::encoding::DefaultFuchsiaResourceDialect));
20032 fidl::decode!(fidl::encoding::Vector<VmoBuffer, 128>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
20033 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20034 {
20035 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20036 }
20037 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20038 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20039 }
20040 }
20041
20042 next_offset += envelope_size;
20043 _next_ordinal_to_read += 1;
20044 if next_offset >= end_offset {
20045 return Ok(());
20046 }
20047
20048 // Decode unknown envelopes for gaps in ordinals.
20049 while _next_ordinal_to_read < 3 {
20050 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20051 _next_ordinal_to_read += 1;
20052 next_offset += envelope_size;
20053 }
20054
20055 let next_out_of_line = decoder.next_out_of_line();
20056 let handles_before = decoder.remaining_handles();
20057 if let Some((inlined, num_bytes, num_handles)) =
20058 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20059 {
20060 let member_inline_size =
20061 <u64 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
20062 if inlined != (member_inline_size <= 4) {
20063 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20064 }
20065 let inner_offset;
20066 let mut inner_depth = depth.clone();
20067 if inlined {
20068 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20069 inner_offset = next_offset;
20070 } else {
20071 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20072 inner_depth.increment()?;
20073 }
20074 let val_ref = self.buffer_collection_id.get_or_insert_with(|| {
20075 fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect)
20076 });
20077 fidl::decode!(
20078 u64,
20079 fidl::encoding::DefaultFuchsiaResourceDialect,
20080 val_ref,
20081 decoder,
20082 inner_offset,
20083 inner_depth
20084 )?;
20085 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20086 {
20087 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20088 }
20089 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20090 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20091 }
20092 }
20093
20094 next_offset += envelope_size;
20095
20096 // Decode the remaining unknown envelopes.
20097 while next_offset < end_offset {
20098 _next_ordinal_to_read += 1;
20099 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20100 next_offset += envelope_size;
20101 }
20102
20103 Ok(())
20104 }
20105 }
20106
20107 impl BufferCollectionSetConstraintsRequest {
20108 #[inline(always)]
20109 fn max_ordinal_present(&self) -> u64 {
20110 if let Some(_) = self.must_match_vmo {
20111 return 2;
20112 }
20113 if let Some(_) = self.constraints {
20114 return 1;
20115 }
20116 0
20117 }
20118 }
20119
20120 impl fidl::encoding::ResourceTypeMarker for BufferCollectionSetConstraintsRequest {
20121 type Borrowed<'a> = &'a mut Self;
20122 fn take_or_borrow<'a>(
20123 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
20124 ) -> Self::Borrowed<'a> {
20125 value
20126 }
20127 }
20128
20129 unsafe impl fidl::encoding::TypeMarker for BufferCollectionSetConstraintsRequest {
20130 type Owned = Self;
20131
20132 #[inline(always)]
20133 fn inline_align(_context: fidl::encoding::Context) -> usize {
20134 8
20135 }
20136
20137 #[inline(always)]
20138 fn inline_size(_context: fidl::encoding::Context) -> usize {
20139 16
20140 }
20141 }
20142
20143 unsafe impl
20144 fidl::encoding::Encode<
20145 BufferCollectionSetConstraintsRequest,
20146 fidl::encoding::DefaultFuchsiaResourceDialect,
20147 > for &mut BufferCollectionSetConstraintsRequest
20148 {
20149 unsafe fn encode(
20150 self,
20151 encoder: &mut fidl::encoding::Encoder<
20152 '_,
20153 fidl::encoding::DefaultFuchsiaResourceDialect,
20154 >,
20155 offset: usize,
20156 mut depth: fidl::encoding::Depth,
20157 ) -> fidl::Result<()> {
20158 encoder.debug_check_bounds::<BufferCollectionSetConstraintsRequest>(offset);
20159 // Vector header
20160 let max_ordinal: u64 = self.max_ordinal_present();
20161 encoder.write_num(max_ordinal, offset);
20162 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
20163 // Calling encoder.out_of_line_offset(0) is not allowed.
20164 if max_ordinal == 0 {
20165 return Ok(());
20166 }
20167 depth.increment()?;
20168 let envelope_size = 8;
20169 let bytes_len = max_ordinal as usize * envelope_size;
20170 #[allow(unused_variables)]
20171 let offset = encoder.out_of_line_offset(bytes_len);
20172 let mut _prev_end_offset: usize = 0;
20173 if 1 > max_ordinal {
20174 return Ok(());
20175 }
20176
20177 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20178 // are envelope_size bytes.
20179 let cur_offset: usize = (1 - 1) * envelope_size;
20180
20181 // Zero reserved fields.
20182 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20183
20184 // Safety:
20185 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20186 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20187 // envelope_size bytes, there is always sufficient room.
20188 fidl::encoding::encode_in_envelope_optional::<
20189 BufferCollectionConstraints,
20190 fidl::encoding::DefaultFuchsiaResourceDialect,
20191 >(
20192 self.constraints
20193 .as_ref()
20194 .map(<BufferCollectionConstraints as fidl::encoding::ValueTypeMarker>::borrow),
20195 encoder,
20196 offset + cur_offset,
20197 depth,
20198 )?;
20199
20200 _prev_end_offset = cur_offset + envelope_size;
20201 if 2 > max_ordinal {
20202 return Ok(());
20203 }
20204
20205 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20206 // are envelope_size bytes.
20207 let cur_offset: usize = (2 - 1) * envelope_size;
20208
20209 // Zero reserved fields.
20210 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20211
20212 // Safety:
20213 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20214 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20215 // envelope_size bytes, there is always sufficient room.
20216 fidl::encoding::encode_in_envelope_optional::<
20217 fidl::encoding::HandleType<
20218 fidl::Vmo,
20219 { fidl::ObjectType::VMO.into_raw() },
20220 2147483648,
20221 >,
20222 fidl::encoding::DefaultFuchsiaResourceDialect,
20223 >(
20224 self.must_match_vmo.as_mut().map(
20225 <fidl::encoding::HandleType<
20226 fidl::Vmo,
20227 { fidl::ObjectType::VMO.into_raw() },
20228 2147483648,
20229 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
20230 ),
20231 encoder,
20232 offset + cur_offset,
20233 depth,
20234 )?;
20235
20236 _prev_end_offset = cur_offset + envelope_size;
20237
20238 Ok(())
20239 }
20240 }
20241
20242 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
20243 for BufferCollectionSetConstraintsRequest
20244 {
20245 #[inline(always)]
20246 fn new_empty() -> Self {
20247 Self::default()
20248 }
20249
20250 unsafe fn decode(
20251 &mut self,
20252 decoder: &mut fidl::encoding::Decoder<
20253 '_,
20254 fidl::encoding::DefaultFuchsiaResourceDialect,
20255 >,
20256 offset: usize,
20257 mut depth: fidl::encoding::Depth,
20258 ) -> fidl::Result<()> {
20259 decoder.debug_check_bounds::<Self>(offset);
20260 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
20261 None => return Err(fidl::Error::NotNullable),
20262 Some(len) => len,
20263 };
20264 // Calling decoder.out_of_line_offset(0) is not allowed.
20265 if len == 0 {
20266 return Ok(());
20267 };
20268 depth.increment()?;
20269 let envelope_size = 8;
20270 let bytes_len = len * envelope_size;
20271 let offset = decoder.out_of_line_offset(bytes_len)?;
20272 // Decode the envelope for each type.
20273 let mut _next_ordinal_to_read = 0;
20274 let mut next_offset = offset;
20275 let end_offset = offset + bytes_len;
20276 _next_ordinal_to_read += 1;
20277 if next_offset >= end_offset {
20278 return Ok(());
20279 }
20280
20281 // Decode unknown envelopes for gaps in ordinals.
20282 while _next_ordinal_to_read < 1 {
20283 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20284 _next_ordinal_to_read += 1;
20285 next_offset += envelope_size;
20286 }
20287
20288 let next_out_of_line = decoder.next_out_of_line();
20289 let handles_before = decoder.remaining_handles();
20290 if let Some((inlined, num_bytes, num_handles)) =
20291 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20292 {
20293 let member_inline_size =
20294 <BufferCollectionConstraints as fidl::encoding::TypeMarker>::inline_size(
20295 decoder.context,
20296 );
20297 if inlined != (member_inline_size <= 4) {
20298 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20299 }
20300 let inner_offset;
20301 let mut inner_depth = depth.clone();
20302 if inlined {
20303 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20304 inner_offset = next_offset;
20305 } else {
20306 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20307 inner_depth.increment()?;
20308 }
20309 let val_ref = self.constraints.get_or_insert_with(|| {
20310 fidl::new_empty!(
20311 BufferCollectionConstraints,
20312 fidl::encoding::DefaultFuchsiaResourceDialect
20313 )
20314 });
20315 fidl::decode!(
20316 BufferCollectionConstraints,
20317 fidl::encoding::DefaultFuchsiaResourceDialect,
20318 val_ref,
20319 decoder,
20320 inner_offset,
20321 inner_depth
20322 )?;
20323 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20324 {
20325 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20326 }
20327 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20328 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20329 }
20330 }
20331
20332 next_offset += envelope_size;
20333 _next_ordinal_to_read += 1;
20334 if next_offset >= end_offset {
20335 return Ok(());
20336 }
20337
20338 // Decode unknown envelopes for gaps in ordinals.
20339 while _next_ordinal_to_read < 2 {
20340 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20341 _next_ordinal_to_read += 1;
20342 next_offset += envelope_size;
20343 }
20344
20345 let next_out_of_line = decoder.next_out_of_line();
20346 let handles_before = decoder.remaining_handles();
20347 if let Some((inlined, num_bytes, num_handles)) =
20348 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20349 {
20350 let member_inline_size = <fidl::encoding::HandleType<
20351 fidl::Vmo,
20352 { fidl::ObjectType::VMO.into_raw() },
20353 2147483648,
20354 > as fidl::encoding::TypeMarker>::inline_size(
20355 decoder.context
20356 );
20357 if inlined != (member_inline_size <= 4) {
20358 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20359 }
20360 let inner_offset;
20361 let mut inner_depth = depth.clone();
20362 if inlined {
20363 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20364 inner_offset = next_offset;
20365 } else {
20366 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20367 inner_depth.increment()?;
20368 }
20369 let val_ref =
20370 self.must_match_vmo.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
20371 fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
20372 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20373 {
20374 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20375 }
20376 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20377 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20378 }
20379 }
20380
20381 next_offset += envelope_size;
20382
20383 // Decode the remaining unknown envelopes.
20384 while next_offset < end_offset {
20385 _next_ordinal_to_read += 1;
20386 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20387 next_offset += envelope_size;
20388 }
20389
20390 Ok(())
20391 }
20392 }
20393
20394 impl BufferCollectionTokenCreateBufferCollectionTokenGroupRequest {
20395 #[inline(always)]
20396 fn max_ordinal_present(&self) -> u64 {
20397 if let Some(_) = self.group_request {
20398 return 1;
20399 }
20400 0
20401 }
20402 }
20403
20404 impl fidl::encoding::ResourceTypeMarker
20405 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
20406 {
20407 type Borrowed<'a> = &'a mut Self;
20408 fn take_or_borrow<'a>(
20409 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
20410 ) -> Self::Borrowed<'a> {
20411 value
20412 }
20413 }
20414
20415 unsafe impl fidl::encoding::TypeMarker
20416 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
20417 {
20418 type Owned = Self;
20419
20420 #[inline(always)]
20421 fn inline_align(_context: fidl::encoding::Context) -> usize {
20422 8
20423 }
20424
20425 #[inline(always)]
20426 fn inline_size(_context: fidl::encoding::Context) -> usize {
20427 16
20428 }
20429 }
20430
20431 unsafe impl
20432 fidl::encoding::Encode<
20433 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
20434 fidl::encoding::DefaultFuchsiaResourceDialect,
20435 > for &mut BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
20436 {
20437 unsafe fn encode(
20438 self,
20439 encoder: &mut fidl::encoding::Encoder<
20440 '_,
20441 fidl::encoding::DefaultFuchsiaResourceDialect,
20442 >,
20443 offset: usize,
20444 mut depth: fidl::encoding::Depth,
20445 ) -> fidl::Result<()> {
20446 encoder
20447 .debug_check_bounds::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
20448 offset,
20449 );
20450 // Vector header
20451 let max_ordinal: u64 = self.max_ordinal_present();
20452 encoder.write_num(max_ordinal, offset);
20453 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
20454 // Calling encoder.out_of_line_offset(0) is not allowed.
20455 if max_ordinal == 0 {
20456 return Ok(());
20457 }
20458 depth.increment()?;
20459 let envelope_size = 8;
20460 let bytes_len = max_ordinal as usize * envelope_size;
20461 #[allow(unused_variables)]
20462 let offset = encoder.out_of_line_offset(bytes_len);
20463 let mut _prev_end_offset: usize = 0;
20464 if 1 > max_ordinal {
20465 return Ok(());
20466 }
20467
20468 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20469 // are envelope_size bytes.
20470 let cur_offset: usize = (1 - 1) * envelope_size;
20471
20472 // Zero reserved fields.
20473 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20474
20475 // Safety:
20476 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20477 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20478 // envelope_size bytes, there is always sufficient room.
20479 fidl::encoding::encode_in_envelope_optional::<
20480 fidl::encoding::Endpoint<
20481 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
20482 >,
20483 fidl::encoding::DefaultFuchsiaResourceDialect,
20484 >(
20485 self.group_request.as_mut().map(
20486 <fidl::encoding::Endpoint<
20487 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
20488 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
20489 ),
20490 encoder,
20491 offset + cur_offset,
20492 depth,
20493 )?;
20494
20495 _prev_end_offset = cur_offset + envelope_size;
20496
20497 Ok(())
20498 }
20499 }
20500
20501 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
20502 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
20503 {
20504 #[inline(always)]
20505 fn new_empty() -> Self {
20506 Self::default()
20507 }
20508
20509 unsafe fn decode(
20510 &mut self,
20511 decoder: &mut fidl::encoding::Decoder<
20512 '_,
20513 fidl::encoding::DefaultFuchsiaResourceDialect,
20514 >,
20515 offset: usize,
20516 mut depth: fidl::encoding::Depth,
20517 ) -> fidl::Result<()> {
20518 decoder.debug_check_bounds::<Self>(offset);
20519 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
20520 None => return Err(fidl::Error::NotNullable),
20521 Some(len) => len,
20522 };
20523 // Calling decoder.out_of_line_offset(0) is not allowed.
20524 if len == 0 {
20525 return Ok(());
20526 };
20527 depth.increment()?;
20528 let envelope_size = 8;
20529 let bytes_len = len * envelope_size;
20530 let offset = decoder.out_of_line_offset(bytes_len)?;
20531 // Decode the envelope for each type.
20532 let mut _next_ordinal_to_read = 0;
20533 let mut next_offset = offset;
20534 let end_offset = offset + bytes_len;
20535 _next_ordinal_to_read += 1;
20536 if next_offset >= end_offset {
20537 return Ok(());
20538 }
20539
20540 // Decode unknown envelopes for gaps in ordinals.
20541 while _next_ordinal_to_read < 1 {
20542 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20543 _next_ordinal_to_read += 1;
20544 next_offset += envelope_size;
20545 }
20546
20547 let next_out_of_line = decoder.next_out_of_line();
20548 let handles_before = decoder.remaining_handles();
20549 if let Some((inlined, num_bytes, num_handles)) =
20550 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20551 {
20552 let member_inline_size = <fidl::encoding::Endpoint<
20553 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
20554 > as fidl::encoding::TypeMarker>::inline_size(
20555 decoder.context
20556 );
20557 if inlined != (member_inline_size <= 4) {
20558 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20559 }
20560 let inner_offset;
20561 let mut inner_depth = depth.clone();
20562 if inlined {
20563 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20564 inner_offset = next_offset;
20565 } else {
20566 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20567 inner_depth.increment()?;
20568 }
20569 let val_ref = self.group_request.get_or_insert_with(|| {
20570 fidl::new_empty!(
20571 fidl::encoding::Endpoint<
20572 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
20573 >,
20574 fidl::encoding::DefaultFuchsiaResourceDialect
20575 )
20576 });
20577 fidl::decode!(
20578 fidl::encoding::Endpoint<
20579 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
20580 >,
20581 fidl::encoding::DefaultFuchsiaResourceDialect,
20582 val_ref,
20583 decoder,
20584 inner_offset,
20585 inner_depth
20586 )?;
20587 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20588 {
20589 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20590 }
20591 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20592 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20593 }
20594 }
20595
20596 next_offset += envelope_size;
20597
20598 // Decode the remaining unknown envelopes.
20599 while next_offset < end_offset {
20600 _next_ordinal_to_read += 1;
20601 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20602 next_offset += envelope_size;
20603 }
20604
20605 Ok(())
20606 }
20607 }
20608
20609 impl BufferCollectionTokenDuplicateRequest {
20610 #[inline(always)]
20611 fn max_ordinal_present(&self) -> u64 {
20612 if let Some(_) = self.token_request {
20613 return 2;
20614 }
20615 if let Some(_) = self.rights_attenuation_mask {
20616 return 1;
20617 }
20618 0
20619 }
20620 }
20621
20622 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateRequest {
20623 type Borrowed<'a> = &'a mut Self;
20624 fn take_or_borrow<'a>(
20625 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
20626 ) -> Self::Borrowed<'a> {
20627 value
20628 }
20629 }
20630
20631 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateRequest {
20632 type Owned = Self;
20633
20634 #[inline(always)]
20635 fn inline_align(_context: fidl::encoding::Context) -> usize {
20636 8
20637 }
20638
20639 #[inline(always)]
20640 fn inline_size(_context: fidl::encoding::Context) -> usize {
20641 16
20642 }
20643 }
20644
20645 unsafe impl
20646 fidl::encoding::Encode<
20647 BufferCollectionTokenDuplicateRequest,
20648 fidl::encoding::DefaultFuchsiaResourceDialect,
20649 > for &mut BufferCollectionTokenDuplicateRequest
20650 {
20651 unsafe fn encode(
20652 self,
20653 encoder: &mut fidl::encoding::Encoder<
20654 '_,
20655 fidl::encoding::DefaultFuchsiaResourceDialect,
20656 >,
20657 offset: usize,
20658 mut depth: fidl::encoding::Depth,
20659 ) -> fidl::Result<()> {
20660 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateRequest>(offset);
20661 // Vector header
20662 let max_ordinal: u64 = self.max_ordinal_present();
20663 encoder.write_num(max_ordinal, offset);
20664 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
20665 // Calling encoder.out_of_line_offset(0) is not allowed.
20666 if max_ordinal == 0 {
20667 return Ok(());
20668 }
20669 depth.increment()?;
20670 let envelope_size = 8;
20671 let bytes_len = max_ordinal as usize * envelope_size;
20672 #[allow(unused_variables)]
20673 let offset = encoder.out_of_line_offset(bytes_len);
20674 let mut _prev_end_offset: usize = 0;
20675 if 1 > max_ordinal {
20676 return Ok(());
20677 }
20678
20679 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20680 // are envelope_size bytes.
20681 let cur_offset: usize = (1 - 1) * envelope_size;
20682
20683 // Zero reserved fields.
20684 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20685
20686 // Safety:
20687 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20688 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20689 // envelope_size bytes, there is always sufficient room.
20690 fidl::encoding::encode_in_envelope_optional::<
20691 fidl::Rights,
20692 fidl::encoding::DefaultFuchsiaResourceDialect,
20693 >(
20694 self.rights_attenuation_mask
20695 .as_ref()
20696 .map(<fidl::Rights as fidl::encoding::ValueTypeMarker>::borrow),
20697 encoder,
20698 offset + cur_offset,
20699 depth,
20700 )?;
20701
20702 _prev_end_offset = cur_offset + envelope_size;
20703 if 2 > max_ordinal {
20704 return Ok(());
20705 }
20706
20707 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20708 // are envelope_size bytes.
20709 let cur_offset: usize = (2 - 1) * envelope_size;
20710
20711 // Zero reserved fields.
20712 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20713
20714 // Safety:
20715 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20716 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20717 // envelope_size bytes, there is always sufficient room.
20718 fidl::encoding::encode_in_envelope_optional::<
20719 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
20720 fidl::encoding::DefaultFuchsiaResourceDialect,
20721 >(
20722 self.token_request.as_mut().map(
20723 <fidl::encoding::Endpoint<
20724 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
20725 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
20726 ),
20727 encoder,
20728 offset + cur_offset,
20729 depth,
20730 )?;
20731
20732 _prev_end_offset = cur_offset + envelope_size;
20733
20734 Ok(())
20735 }
20736 }
20737
20738 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
20739 for BufferCollectionTokenDuplicateRequest
20740 {
20741 #[inline(always)]
20742 fn new_empty() -> Self {
20743 Self::default()
20744 }
20745
20746 unsafe fn decode(
20747 &mut self,
20748 decoder: &mut fidl::encoding::Decoder<
20749 '_,
20750 fidl::encoding::DefaultFuchsiaResourceDialect,
20751 >,
20752 offset: usize,
20753 mut depth: fidl::encoding::Depth,
20754 ) -> fidl::Result<()> {
20755 decoder.debug_check_bounds::<Self>(offset);
20756 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
20757 None => return Err(fidl::Error::NotNullable),
20758 Some(len) => len,
20759 };
20760 // Calling decoder.out_of_line_offset(0) is not allowed.
20761 if len == 0 {
20762 return Ok(());
20763 };
20764 depth.increment()?;
20765 let envelope_size = 8;
20766 let bytes_len = len * envelope_size;
20767 let offset = decoder.out_of_line_offset(bytes_len)?;
20768 // Decode the envelope for each type.
20769 let mut _next_ordinal_to_read = 0;
20770 let mut next_offset = offset;
20771 let end_offset = offset + bytes_len;
20772 _next_ordinal_to_read += 1;
20773 if next_offset >= end_offset {
20774 return Ok(());
20775 }
20776
20777 // Decode unknown envelopes for gaps in ordinals.
20778 while _next_ordinal_to_read < 1 {
20779 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20780 _next_ordinal_to_read += 1;
20781 next_offset += envelope_size;
20782 }
20783
20784 let next_out_of_line = decoder.next_out_of_line();
20785 let handles_before = decoder.remaining_handles();
20786 if let Some((inlined, num_bytes, num_handles)) =
20787 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20788 {
20789 let member_inline_size =
20790 <fidl::Rights as fidl::encoding::TypeMarker>::inline_size(decoder.context);
20791 if inlined != (member_inline_size <= 4) {
20792 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20793 }
20794 let inner_offset;
20795 let mut inner_depth = depth.clone();
20796 if inlined {
20797 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20798 inner_offset = next_offset;
20799 } else {
20800 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20801 inner_depth.increment()?;
20802 }
20803 let val_ref = self.rights_attenuation_mask.get_or_insert_with(|| {
20804 fidl::new_empty!(fidl::Rights, fidl::encoding::DefaultFuchsiaResourceDialect)
20805 });
20806 fidl::decode!(
20807 fidl::Rights,
20808 fidl::encoding::DefaultFuchsiaResourceDialect,
20809 val_ref,
20810 decoder,
20811 inner_offset,
20812 inner_depth
20813 )?;
20814 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20815 {
20816 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20817 }
20818 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20819 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20820 }
20821 }
20822
20823 next_offset += envelope_size;
20824 _next_ordinal_to_read += 1;
20825 if next_offset >= end_offset {
20826 return Ok(());
20827 }
20828
20829 // Decode unknown envelopes for gaps in ordinals.
20830 while _next_ordinal_to_read < 2 {
20831 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20832 _next_ordinal_to_read += 1;
20833 next_offset += envelope_size;
20834 }
20835
20836 let next_out_of_line = decoder.next_out_of_line();
20837 let handles_before = decoder.remaining_handles();
20838 if let Some((inlined, num_bytes, num_handles)) =
20839 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20840 {
20841 let member_inline_size = <fidl::encoding::Endpoint<
20842 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
20843 > as fidl::encoding::TypeMarker>::inline_size(
20844 decoder.context
20845 );
20846 if inlined != (member_inline_size <= 4) {
20847 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20848 }
20849 let inner_offset;
20850 let mut inner_depth = depth.clone();
20851 if inlined {
20852 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20853 inner_offset = next_offset;
20854 } else {
20855 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20856 inner_depth.increment()?;
20857 }
20858 let val_ref = self.token_request.get_or_insert_with(|| {
20859 fidl::new_empty!(
20860 fidl::encoding::Endpoint<
20861 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
20862 >,
20863 fidl::encoding::DefaultFuchsiaResourceDialect
20864 )
20865 });
20866 fidl::decode!(
20867 fidl::encoding::Endpoint<
20868 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
20869 >,
20870 fidl::encoding::DefaultFuchsiaResourceDialect,
20871 val_ref,
20872 decoder,
20873 inner_offset,
20874 inner_depth
20875 )?;
20876 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20877 {
20878 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20879 }
20880 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20881 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20882 }
20883 }
20884
20885 next_offset += envelope_size;
20886
20887 // Decode the remaining unknown envelopes.
20888 while next_offset < end_offset {
20889 _next_ordinal_to_read += 1;
20890 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20891 next_offset += envelope_size;
20892 }
20893
20894 Ok(())
20895 }
20896 }
20897
20898 impl BufferCollectionTokenGroupCreateChildRequest {
20899 #[inline(always)]
20900 fn max_ordinal_present(&self) -> u64 {
20901 if let Some(_) = self.rights_attenuation_mask {
20902 return 2;
20903 }
20904 if let Some(_) = self.token_request {
20905 return 1;
20906 }
20907 0
20908 }
20909 }
20910
20911 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildRequest {
20912 type Borrowed<'a> = &'a mut Self;
20913 fn take_or_borrow<'a>(
20914 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
20915 ) -> Self::Borrowed<'a> {
20916 value
20917 }
20918 }
20919
20920 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildRequest {
20921 type Owned = Self;
20922
20923 #[inline(always)]
20924 fn inline_align(_context: fidl::encoding::Context) -> usize {
20925 8
20926 }
20927
20928 #[inline(always)]
20929 fn inline_size(_context: fidl::encoding::Context) -> usize {
20930 16
20931 }
20932 }
20933
20934 unsafe impl
20935 fidl::encoding::Encode<
20936 BufferCollectionTokenGroupCreateChildRequest,
20937 fidl::encoding::DefaultFuchsiaResourceDialect,
20938 > for &mut BufferCollectionTokenGroupCreateChildRequest
20939 {
20940 unsafe fn encode(
20941 self,
20942 encoder: &mut fidl::encoding::Encoder<
20943 '_,
20944 fidl::encoding::DefaultFuchsiaResourceDialect,
20945 >,
20946 offset: usize,
20947 mut depth: fidl::encoding::Depth,
20948 ) -> fidl::Result<()> {
20949 encoder.debug_check_bounds::<BufferCollectionTokenGroupCreateChildRequest>(offset);
20950 // Vector header
20951 let max_ordinal: u64 = self.max_ordinal_present();
20952 encoder.write_num(max_ordinal, offset);
20953 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
20954 // Calling encoder.out_of_line_offset(0) is not allowed.
20955 if max_ordinal == 0 {
20956 return Ok(());
20957 }
20958 depth.increment()?;
20959 let envelope_size = 8;
20960 let bytes_len = max_ordinal as usize * envelope_size;
20961 #[allow(unused_variables)]
20962 let offset = encoder.out_of_line_offset(bytes_len);
20963 let mut _prev_end_offset: usize = 0;
20964 if 1 > max_ordinal {
20965 return Ok(());
20966 }
20967
20968 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20969 // are envelope_size bytes.
20970 let cur_offset: usize = (1 - 1) * envelope_size;
20971
20972 // Zero reserved fields.
20973 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20974
20975 // Safety:
20976 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20977 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20978 // envelope_size bytes, there is always sufficient room.
20979 fidl::encoding::encode_in_envelope_optional::<
20980 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
20981 fidl::encoding::DefaultFuchsiaResourceDialect,
20982 >(
20983 self.token_request.as_mut().map(
20984 <fidl::encoding::Endpoint<
20985 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
20986 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
20987 ),
20988 encoder,
20989 offset + cur_offset,
20990 depth,
20991 )?;
20992
20993 _prev_end_offset = cur_offset + envelope_size;
20994 if 2 > max_ordinal {
20995 return Ok(());
20996 }
20997
20998 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20999 // are envelope_size bytes.
21000 let cur_offset: usize = (2 - 1) * envelope_size;
21001
21002 // Zero reserved fields.
21003 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
21004
21005 // Safety:
21006 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
21007 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
21008 // envelope_size bytes, there is always sufficient room.
21009 fidl::encoding::encode_in_envelope_optional::<
21010 fidl::Rights,
21011 fidl::encoding::DefaultFuchsiaResourceDialect,
21012 >(
21013 self.rights_attenuation_mask
21014 .as_ref()
21015 .map(<fidl::Rights as fidl::encoding::ValueTypeMarker>::borrow),
21016 encoder,
21017 offset + cur_offset,
21018 depth,
21019 )?;
21020
21021 _prev_end_offset = cur_offset + envelope_size;
21022
21023 Ok(())
21024 }
21025 }
21026
21027 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
21028 for BufferCollectionTokenGroupCreateChildRequest
21029 {
21030 #[inline(always)]
21031 fn new_empty() -> Self {
21032 Self::default()
21033 }
21034
21035 unsafe fn decode(
21036 &mut self,
21037 decoder: &mut fidl::encoding::Decoder<
21038 '_,
21039 fidl::encoding::DefaultFuchsiaResourceDialect,
21040 >,
21041 offset: usize,
21042 mut depth: fidl::encoding::Depth,
21043 ) -> fidl::Result<()> {
21044 decoder.debug_check_bounds::<Self>(offset);
21045 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
21046 None => return Err(fidl::Error::NotNullable),
21047 Some(len) => len,
21048 };
21049 // Calling decoder.out_of_line_offset(0) is not allowed.
21050 if len == 0 {
21051 return Ok(());
21052 };
21053 depth.increment()?;
21054 let envelope_size = 8;
21055 let bytes_len = len * envelope_size;
21056 let offset = decoder.out_of_line_offset(bytes_len)?;
21057 // Decode the envelope for each type.
21058 let mut _next_ordinal_to_read = 0;
21059 let mut next_offset = offset;
21060 let end_offset = offset + bytes_len;
21061 _next_ordinal_to_read += 1;
21062 if next_offset >= end_offset {
21063 return Ok(());
21064 }
21065
21066 // Decode unknown envelopes for gaps in ordinals.
21067 while _next_ordinal_to_read < 1 {
21068 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21069 _next_ordinal_to_read += 1;
21070 next_offset += envelope_size;
21071 }
21072
21073 let next_out_of_line = decoder.next_out_of_line();
21074 let handles_before = decoder.remaining_handles();
21075 if let Some((inlined, num_bytes, num_handles)) =
21076 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21077 {
21078 let member_inline_size = <fidl::encoding::Endpoint<
21079 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
21080 > as fidl::encoding::TypeMarker>::inline_size(
21081 decoder.context
21082 );
21083 if inlined != (member_inline_size <= 4) {
21084 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21085 }
21086 let inner_offset;
21087 let mut inner_depth = depth.clone();
21088 if inlined {
21089 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21090 inner_offset = next_offset;
21091 } else {
21092 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21093 inner_depth.increment()?;
21094 }
21095 let val_ref = self.token_request.get_or_insert_with(|| {
21096 fidl::new_empty!(
21097 fidl::encoding::Endpoint<
21098 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
21099 >,
21100 fidl::encoding::DefaultFuchsiaResourceDialect
21101 )
21102 });
21103 fidl::decode!(
21104 fidl::encoding::Endpoint<
21105 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
21106 >,
21107 fidl::encoding::DefaultFuchsiaResourceDialect,
21108 val_ref,
21109 decoder,
21110 inner_offset,
21111 inner_depth
21112 )?;
21113 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21114 {
21115 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21116 }
21117 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21118 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21119 }
21120 }
21121
21122 next_offset += envelope_size;
21123 _next_ordinal_to_read += 1;
21124 if next_offset >= end_offset {
21125 return Ok(());
21126 }
21127
21128 // Decode unknown envelopes for gaps in ordinals.
21129 while _next_ordinal_to_read < 2 {
21130 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21131 _next_ordinal_to_read += 1;
21132 next_offset += envelope_size;
21133 }
21134
21135 let next_out_of_line = decoder.next_out_of_line();
21136 let handles_before = decoder.remaining_handles();
21137 if let Some((inlined, num_bytes, num_handles)) =
21138 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21139 {
21140 let member_inline_size =
21141 <fidl::Rights as fidl::encoding::TypeMarker>::inline_size(decoder.context);
21142 if inlined != (member_inline_size <= 4) {
21143 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21144 }
21145 let inner_offset;
21146 let mut inner_depth = depth.clone();
21147 if inlined {
21148 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21149 inner_offset = next_offset;
21150 } else {
21151 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21152 inner_depth.increment()?;
21153 }
21154 let val_ref = self.rights_attenuation_mask.get_or_insert_with(|| {
21155 fidl::new_empty!(fidl::Rights, fidl::encoding::DefaultFuchsiaResourceDialect)
21156 });
21157 fidl::decode!(
21158 fidl::Rights,
21159 fidl::encoding::DefaultFuchsiaResourceDialect,
21160 val_ref,
21161 decoder,
21162 inner_offset,
21163 inner_depth
21164 )?;
21165 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21166 {
21167 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21168 }
21169 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21170 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21171 }
21172 }
21173
21174 next_offset += envelope_size;
21175
21176 // Decode the remaining unknown envelopes.
21177 while next_offset < end_offset {
21178 _next_ordinal_to_read += 1;
21179 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21180 next_offset += envelope_size;
21181 }
21182
21183 Ok(())
21184 }
21185 }
21186
21187 impl BufferCollectionTokenGroupCreateChildrenSyncResponse {
21188 #[inline(always)]
21189 fn max_ordinal_present(&self) -> u64 {
21190 if let Some(_) = self.tokens {
21191 return 1;
21192 }
21193 0
21194 }
21195 }
21196
21197 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
21198 type Borrowed<'a> = &'a mut Self;
21199 fn take_or_borrow<'a>(
21200 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
21201 ) -> Self::Borrowed<'a> {
21202 value
21203 }
21204 }
21205
21206 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
21207 type Owned = Self;
21208
21209 #[inline(always)]
21210 fn inline_align(_context: fidl::encoding::Context) -> usize {
21211 8
21212 }
21213
21214 #[inline(always)]
21215 fn inline_size(_context: fidl::encoding::Context) -> usize {
21216 16
21217 }
21218 }
21219
21220 unsafe impl
21221 fidl::encoding::Encode<
21222 BufferCollectionTokenGroupCreateChildrenSyncResponse,
21223 fidl::encoding::DefaultFuchsiaResourceDialect,
21224 > for &mut BufferCollectionTokenGroupCreateChildrenSyncResponse
21225 {
21226 unsafe fn encode(
21227 self,
21228 encoder: &mut fidl::encoding::Encoder<
21229 '_,
21230 fidl::encoding::DefaultFuchsiaResourceDialect,
21231 >,
21232 offset: usize,
21233 mut depth: fidl::encoding::Depth,
21234 ) -> fidl::Result<()> {
21235 encoder
21236 .debug_check_bounds::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(offset);
21237 // Vector header
21238 let max_ordinal: u64 = self.max_ordinal_present();
21239 encoder.write_num(max_ordinal, offset);
21240 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
21241 // Calling encoder.out_of_line_offset(0) is not allowed.
21242 if max_ordinal == 0 {
21243 return Ok(());
21244 }
21245 depth.increment()?;
21246 let envelope_size = 8;
21247 let bytes_len = max_ordinal as usize * envelope_size;
21248 #[allow(unused_variables)]
21249 let offset = encoder.out_of_line_offset(bytes_len);
21250 let mut _prev_end_offset: usize = 0;
21251 if 1 > max_ordinal {
21252 return Ok(());
21253 }
21254
21255 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
21256 // are envelope_size bytes.
21257 let cur_offset: usize = (1 - 1) * envelope_size;
21258
21259 // Zero reserved fields.
21260 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
21261
21262 // Safety:
21263 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
21264 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
21265 // envelope_size bytes, there is always sufficient room.
21266 fidl::encoding::encode_in_envelope_optional::<
21267 fidl::encoding::Vector<
21268 fidl::encoding::Endpoint<
21269 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21270 >,
21271 64,
21272 >,
21273 fidl::encoding::DefaultFuchsiaResourceDialect,
21274 >(
21275 self.tokens.as_mut().map(
21276 <fidl::encoding::Vector<
21277 fidl::encoding::Endpoint<
21278 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21279 >,
21280 64,
21281 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
21282 ),
21283 encoder,
21284 offset + cur_offset,
21285 depth,
21286 )?;
21287
21288 _prev_end_offset = cur_offset + envelope_size;
21289
21290 Ok(())
21291 }
21292 }
21293
21294 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
21295 for BufferCollectionTokenGroupCreateChildrenSyncResponse
21296 {
21297 #[inline(always)]
21298 fn new_empty() -> Self {
21299 Self::default()
21300 }
21301
21302 unsafe fn decode(
21303 &mut self,
21304 decoder: &mut fidl::encoding::Decoder<
21305 '_,
21306 fidl::encoding::DefaultFuchsiaResourceDialect,
21307 >,
21308 offset: usize,
21309 mut depth: fidl::encoding::Depth,
21310 ) -> fidl::Result<()> {
21311 decoder.debug_check_bounds::<Self>(offset);
21312 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
21313 None => return Err(fidl::Error::NotNullable),
21314 Some(len) => len,
21315 };
21316 // Calling decoder.out_of_line_offset(0) is not allowed.
21317 if len == 0 {
21318 return Ok(());
21319 };
21320 depth.increment()?;
21321 let envelope_size = 8;
21322 let bytes_len = len * envelope_size;
21323 let offset = decoder.out_of_line_offset(bytes_len)?;
21324 // Decode the envelope for each type.
21325 let mut _next_ordinal_to_read = 0;
21326 let mut next_offset = offset;
21327 let end_offset = offset + bytes_len;
21328 _next_ordinal_to_read += 1;
21329 if next_offset >= end_offset {
21330 return Ok(());
21331 }
21332
21333 // Decode unknown envelopes for gaps in ordinals.
21334 while _next_ordinal_to_read < 1 {
21335 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21336 _next_ordinal_to_read += 1;
21337 next_offset += envelope_size;
21338 }
21339
21340 let next_out_of_line = decoder.next_out_of_line();
21341 let handles_before = decoder.remaining_handles();
21342 if let Some((inlined, num_bytes, num_handles)) =
21343 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21344 {
21345 let member_inline_size = <fidl::encoding::Vector<
21346 fidl::encoding::Endpoint<
21347 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21348 >,
21349 64,
21350 > as fidl::encoding::TypeMarker>::inline_size(
21351 decoder.context
21352 );
21353 if inlined != (member_inline_size <= 4) {
21354 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21355 }
21356 let inner_offset;
21357 let mut inner_depth = depth.clone();
21358 if inlined {
21359 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21360 inner_offset = next_offset;
21361 } else {
21362 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21363 inner_depth.increment()?;
21364 }
21365 let val_ref = self.tokens.get_or_insert_with(|| {
21366 fidl::new_empty!(
21367 fidl::encoding::Vector<
21368 fidl::encoding::Endpoint<
21369 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21370 >,
21371 64,
21372 >,
21373 fidl::encoding::DefaultFuchsiaResourceDialect
21374 )
21375 });
21376 fidl::decode!(
21377 fidl::encoding::Vector<
21378 fidl::encoding::Endpoint<
21379 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21380 >,
21381 64,
21382 >,
21383 fidl::encoding::DefaultFuchsiaResourceDialect,
21384 val_ref,
21385 decoder,
21386 inner_offset,
21387 inner_depth
21388 )?;
21389 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21390 {
21391 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21392 }
21393 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21394 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21395 }
21396 }
21397
21398 next_offset += envelope_size;
21399
21400 // Decode the remaining unknown envelopes.
21401 while next_offset < end_offset {
21402 _next_ordinal_to_read += 1;
21403 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21404 next_offset += envelope_size;
21405 }
21406
21407 Ok(())
21408 }
21409 }
21410
21411 impl BufferCollectionTokenDuplicateSyncResponse {
21412 #[inline(always)]
21413 fn max_ordinal_present(&self) -> u64 {
21414 if let Some(_) = self.tokens {
21415 return 1;
21416 }
21417 0
21418 }
21419 }
21420
21421 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateSyncResponse {
21422 type Borrowed<'a> = &'a mut Self;
21423 fn take_or_borrow<'a>(
21424 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
21425 ) -> Self::Borrowed<'a> {
21426 value
21427 }
21428 }
21429
21430 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateSyncResponse {
21431 type Owned = Self;
21432
21433 #[inline(always)]
21434 fn inline_align(_context: fidl::encoding::Context) -> usize {
21435 8
21436 }
21437
21438 #[inline(always)]
21439 fn inline_size(_context: fidl::encoding::Context) -> usize {
21440 16
21441 }
21442 }
21443
21444 unsafe impl
21445 fidl::encoding::Encode<
21446 BufferCollectionTokenDuplicateSyncResponse,
21447 fidl::encoding::DefaultFuchsiaResourceDialect,
21448 > for &mut BufferCollectionTokenDuplicateSyncResponse
21449 {
21450 unsafe fn encode(
21451 self,
21452 encoder: &mut fidl::encoding::Encoder<
21453 '_,
21454 fidl::encoding::DefaultFuchsiaResourceDialect,
21455 >,
21456 offset: usize,
21457 mut depth: fidl::encoding::Depth,
21458 ) -> fidl::Result<()> {
21459 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateSyncResponse>(offset);
21460 // Vector header
21461 let max_ordinal: u64 = self.max_ordinal_present();
21462 encoder.write_num(max_ordinal, offset);
21463 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
21464 // Calling encoder.out_of_line_offset(0) is not allowed.
21465 if max_ordinal == 0 {
21466 return Ok(());
21467 }
21468 depth.increment()?;
21469 let envelope_size = 8;
21470 let bytes_len = max_ordinal as usize * envelope_size;
21471 #[allow(unused_variables)]
21472 let offset = encoder.out_of_line_offset(bytes_len);
21473 let mut _prev_end_offset: usize = 0;
21474 if 1 > max_ordinal {
21475 return Ok(());
21476 }
21477
21478 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
21479 // are envelope_size bytes.
21480 let cur_offset: usize = (1 - 1) * envelope_size;
21481
21482 // Zero reserved fields.
21483 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
21484
21485 // Safety:
21486 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
21487 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
21488 // envelope_size bytes, there is always sufficient room.
21489 fidl::encoding::encode_in_envelope_optional::<
21490 fidl::encoding::Vector<
21491 fidl::encoding::Endpoint<
21492 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21493 >,
21494 64,
21495 >,
21496 fidl::encoding::DefaultFuchsiaResourceDialect,
21497 >(
21498 self.tokens.as_mut().map(
21499 <fidl::encoding::Vector<
21500 fidl::encoding::Endpoint<
21501 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21502 >,
21503 64,
21504 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
21505 ),
21506 encoder,
21507 offset + cur_offset,
21508 depth,
21509 )?;
21510
21511 _prev_end_offset = cur_offset + envelope_size;
21512
21513 Ok(())
21514 }
21515 }
21516
21517 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
21518 for BufferCollectionTokenDuplicateSyncResponse
21519 {
21520 #[inline(always)]
21521 fn new_empty() -> Self {
21522 Self::default()
21523 }
21524
21525 unsafe fn decode(
21526 &mut self,
21527 decoder: &mut fidl::encoding::Decoder<
21528 '_,
21529 fidl::encoding::DefaultFuchsiaResourceDialect,
21530 >,
21531 offset: usize,
21532 mut depth: fidl::encoding::Depth,
21533 ) -> fidl::Result<()> {
21534 decoder.debug_check_bounds::<Self>(offset);
21535 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
21536 None => return Err(fidl::Error::NotNullable),
21537 Some(len) => len,
21538 };
21539 // Calling decoder.out_of_line_offset(0) is not allowed.
21540 if len == 0 {
21541 return Ok(());
21542 };
21543 depth.increment()?;
21544 let envelope_size = 8;
21545 let bytes_len = len * envelope_size;
21546 let offset = decoder.out_of_line_offset(bytes_len)?;
21547 // Decode the envelope for each type.
21548 let mut _next_ordinal_to_read = 0;
21549 let mut next_offset = offset;
21550 let end_offset = offset + bytes_len;
21551 _next_ordinal_to_read += 1;
21552 if next_offset >= end_offset {
21553 return Ok(());
21554 }
21555
21556 // Decode unknown envelopes for gaps in ordinals.
21557 while _next_ordinal_to_read < 1 {
21558 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21559 _next_ordinal_to_read += 1;
21560 next_offset += envelope_size;
21561 }
21562
21563 let next_out_of_line = decoder.next_out_of_line();
21564 let handles_before = decoder.remaining_handles();
21565 if let Some((inlined, num_bytes, num_handles)) =
21566 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21567 {
21568 let member_inline_size = <fidl::encoding::Vector<
21569 fidl::encoding::Endpoint<
21570 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21571 >,
21572 64,
21573 > as fidl::encoding::TypeMarker>::inline_size(
21574 decoder.context
21575 );
21576 if inlined != (member_inline_size <= 4) {
21577 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21578 }
21579 let inner_offset;
21580 let mut inner_depth = depth.clone();
21581 if inlined {
21582 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21583 inner_offset = next_offset;
21584 } else {
21585 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21586 inner_depth.increment()?;
21587 }
21588 let val_ref = self.tokens.get_or_insert_with(|| {
21589 fidl::new_empty!(
21590 fidl::encoding::Vector<
21591 fidl::encoding::Endpoint<
21592 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21593 >,
21594 64,
21595 >,
21596 fidl::encoding::DefaultFuchsiaResourceDialect
21597 )
21598 });
21599 fidl::decode!(
21600 fidl::encoding::Vector<
21601 fidl::encoding::Endpoint<
21602 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21603 >,
21604 64,
21605 >,
21606 fidl::encoding::DefaultFuchsiaResourceDialect,
21607 val_ref,
21608 decoder,
21609 inner_offset,
21610 inner_depth
21611 )?;
21612 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21613 {
21614 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21615 }
21616 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21617 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21618 }
21619 }
21620
21621 next_offset += envelope_size;
21622
21623 // Decode the remaining unknown envelopes.
21624 while next_offset < end_offset {
21625 _next_ordinal_to_read += 1;
21626 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21627 next_offset += envelope_size;
21628 }
21629
21630 Ok(())
21631 }
21632 }
21633
21634 impl BufferCollectionWaitForAllBuffersAllocatedResponse {
21635 #[inline(always)]
21636 fn max_ordinal_present(&self) -> u64 {
21637 if let Some(_) = self.buffer_collection_info {
21638 return 1;
21639 }
21640 0
21641 }
21642 }
21643
21644 impl fidl::encoding::ResourceTypeMarker for BufferCollectionWaitForAllBuffersAllocatedResponse {
21645 type Borrowed<'a> = &'a mut Self;
21646 fn take_or_borrow<'a>(
21647 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
21648 ) -> Self::Borrowed<'a> {
21649 value
21650 }
21651 }
21652
21653 unsafe impl fidl::encoding::TypeMarker for BufferCollectionWaitForAllBuffersAllocatedResponse {
21654 type Owned = Self;
21655
21656 #[inline(always)]
21657 fn inline_align(_context: fidl::encoding::Context) -> usize {
21658 8
21659 }
21660
21661 #[inline(always)]
21662 fn inline_size(_context: fidl::encoding::Context) -> usize {
21663 16
21664 }
21665 }
21666
21667 unsafe impl
21668 fidl::encoding::Encode<
21669 BufferCollectionWaitForAllBuffersAllocatedResponse,
21670 fidl::encoding::DefaultFuchsiaResourceDialect,
21671 > for &mut BufferCollectionWaitForAllBuffersAllocatedResponse
21672 {
21673 unsafe fn encode(
21674 self,
21675 encoder: &mut fidl::encoding::Encoder<
21676 '_,
21677 fidl::encoding::DefaultFuchsiaResourceDialect,
21678 >,
21679 offset: usize,
21680 mut depth: fidl::encoding::Depth,
21681 ) -> fidl::Result<()> {
21682 encoder
21683 .debug_check_bounds::<BufferCollectionWaitForAllBuffersAllocatedResponse>(offset);
21684 // Vector header
21685 let max_ordinal: u64 = self.max_ordinal_present();
21686 encoder.write_num(max_ordinal, offset);
21687 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
21688 // Calling encoder.out_of_line_offset(0) is not allowed.
21689 if max_ordinal == 0 {
21690 return Ok(());
21691 }
21692 depth.increment()?;
21693 let envelope_size = 8;
21694 let bytes_len = max_ordinal as usize * envelope_size;
21695 #[allow(unused_variables)]
21696 let offset = encoder.out_of_line_offset(bytes_len);
21697 let mut _prev_end_offset: usize = 0;
21698 if 1 > max_ordinal {
21699 return Ok(());
21700 }
21701
21702 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
21703 // are envelope_size bytes.
21704 let cur_offset: usize = (1 - 1) * envelope_size;
21705
21706 // Zero reserved fields.
21707 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
21708
21709 // Safety:
21710 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
21711 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
21712 // envelope_size bytes, there is always sufficient room.
21713 fidl::encoding::encode_in_envelope_optional::<
21714 BufferCollectionInfo,
21715 fidl::encoding::DefaultFuchsiaResourceDialect,
21716 >(
21717 self.buffer_collection_info.as_mut().map(
21718 <BufferCollectionInfo as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
21719 ),
21720 encoder,
21721 offset + cur_offset,
21722 depth,
21723 )?;
21724
21725 _prev_end_offset = cur_offset + envelope_size;
21726
21727 Ok(())
21728 }
21729 }
21730
21731 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
21732 for BufferCollectionWaitForAllBuffersAllocatedResponse
21733 {
21734 #[inline(always)]
21735 fn new_empty() -> Self {
21736 Self::default()
21737 }
21738
21739 unsafe fn decode(
21740 &mut self,
21741 decoder: &mut fidl::encoding::Decoder<
21742 '_,
21743 fidl::encoding::DefaultFuchsiaResourceDialect,
21744 >,
21745 offset: usize,
21746 mut depth: fidl::encoding::Depth,
21747 ) -> fidl::Result<()> {
21748 decoder.debug_check_bounds::<Self>(offset);
21749 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
21750 None => return Err(fidl::Error::NotNullable),
21751 Some(len) => len,
21752 };
21753 // Calling decoder.out_of_line_offset(0) is not allowed.
21754 if len == 0 {
21755 return Ok(());
21756 };
21757 depth.increment()?;
21758 let envelope_size = 8;
21759 let bytes_len = len * envelope_size;
21760 let offset = decoder.out_of_line_offset(bytes_len)?;
21761 // Decode the envelope for each type.
21762 let mut _next_ordinal_to_read = 0;
21763 let mut next_offset = offset;
21764 let end_offset = offset + bytes_len;
21765 _next_ordinal_to_read += 1;
21766 if next_offset >= end_offset {
21767 return Ok(());
21768 }
21769
21770 // Decode unknown envelopes for gaps in ordinals.
21771 while _next_ordinal_to_read < 1 {
21772 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21773 _next_ordinal_to_read += 1;
21774 next_offset += envelope_size;
21775 }
21776
21777 let next_out_of_line = decoder.next_out_of_line();
21778 let handles_before = decoder.remaining_handles();
21779 if let Some((inlined, num_bytes, num_handles)) =
21780 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21781 {
21782 let member_inline_size =
21783 <BufferCollectionInfo as fidl::encoding::TypeMarker>::inline_size(
21784 decoder.context,
21785 );
21786 if inlined != (member_inline_size <= 4) {
21787 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21788 }
21789 let inner_offset;
21790 let mut inner_depth = depth.clone();
21791 if inlined {
21792 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21793 inner_offset = next_offset;
21794 } else {
21795 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21796 inner_depth.increment()?;
21797 }
21798 let val_ref = self.buffer_collection_info.get_or_insert_with(|| {
21799 fidl::new_empty!(
21800 BufferCollectionInfo,
21801 fidl::encoding::DefaultFuchsiaResourceDialect
21802 )
21803 });
21804 fidl::decode!(
21805 BufferCollectionInfo,
21806 fidl::encoding::DefaultFuchsiaResourceDialect,
21807 val_ref,
21808 decoder,
21809 inner_offset,
21810 inner_depth
21811 )?;
21812 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21813 {
21814 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21815 }
21816 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21817 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21818 }
21819 }
21820
21821 next_offset += envelope_size;
21822
21823 // Decode the remaining unknown envelopes.
21824 while next_offset < end_offset {
21825 _next_ordinal_to_read += 1;
21826 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21827 next_offset += envelope_size;
21828 }
21829
21830 Ok(())
21831 }
21832 }
21833
21834 impl NodeAttachNodeTrackingRequest {
21835 #[inline(always)]
21836 fn max_ordinal_present(&self) -> u64 {
21837 if let Some(_) = self.server_end {
21838 return 1;
21839 }
21840 0
21841 }
21842 }
21843
21844 impl fidl::encoding::ResourceTypeMarker for NodeAttachNodeTrackingRequest {
21845 type Borrowed<'a> = &'a mut Self;
21846 fn take_or_borrow<'a>(
21847 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
21848 ) -> Self::Borrowed<'a> {
21849 value
21850 }
21851 }
21852
21853 unsafe impl fidl::encoding::TypeMarker for NodeAttachNodeTrackingRequest {
21854 type Owned = Self;
21855
21856 #[inline(always)]
21857 fn inline_align(_context: fidl::encoding::Context) -> usize {
21858 8
21859 }
21860
21861 #[inline(always)]
21862 fn inline_size(_context: fidl::encoding::Context) -> usize {
21863 16
21864 }
21865 }
21866
21867 unsafe impl
21868 fidl::encoding::Encode<
21869 NodeAttachNodeTrackingRequest,
21870 fidl::encoding::DefaultFuchsiaResourceDialect,
21871 > for &mut NodeAttachNodeTrackingRequest
21872 {
21873 unsafe fn encode(
21874 self,
21875 encoder: &mut fidl::encoding::Encoder<
21876 '_,
21877 fidl::encoding::DefaultFuchsiaResourceDialect,
21878 >,
21879 offset: usize,
21880 mut depth: fidl::encoding::Depth,
21881 ) -> fidl::Result<()> {
21882 encoder.debug_check_bounds::<NodeAttachNodeTrackingRequest>(offset);
21883 // Vector header
21884 let max_ordinal: u64 = self.max_ordinal_present();
21885 encoder.write_num(max_ordinal, offset);
21886 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
21887 // Calling encoder.out_of_line_offset(0) is not allowed.
21888 if max_ordinal == 0 {
21889 return Ok(());
21890 }
21891 depth.increment()?;
21892 let envelope_size = 8;
21893 let bytes_len = max_ordinal as usize * envelope_size;
21894 #[allow(unused_variables)]
21895 let offset = encoder.out_of_line_offset(bytes_len);
21896 let mut _prev_end_offset: usize = 0;
21897 if 1 > max_ordinal {
21898 return Ok(());
21899 }
21900
21901 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
21902 // are envelope_size bytes.
21903 let cur_offset: usize = (1 - 1) * envelope_size;
21904
21905 // Zero reserved fields.
21906 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
21907
21908 // Safety:
21909 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
21910 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
21911 // envelope_size bytes, there is always sufficient room.
21912 fidl::encoding::encode_in_envelope_optional::<
21913 fidl::encoding::HandleType<
21914 fidl::EventPair,
21915 { fidl::ObjectType::EVENTPAIR.into_raw() },
21916 2147483648,
21917 >,
21918 fidl::encoding::DefaultFuchsiaResourceDialect,
21919 >(
21920 self.server_end.as_mut().map(
21921 <fidl::encoding::HandleType<
21922 fidl::EventPair,
21923 { fidl::ObjectType::EVENTPAIR.into_raw() },
21924 2147483648,
21925 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
21926 ),
21927 encoder,
21928 offset + cur_offset,
21929 depth,
21930 )?;
21931
21932 _prev_end_offset = cur_offset + envelope_size;
21933
21934 Ok(())
21935 }
21936 }
21937
21938 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
21939 for NodeAttachNodeTrackingRequest
21940 {
21941 #[inline(always)]
21942 fn new_empty() -> Self {
21943 Self::default()
21944 }
21945
21946 unsafe fn decode(
21947 &mut self,
21948 decoder: &mut fidl::encoding::Decoder<
21949 '_,
21950 fidl::encoding::DefaultFuchsiaResourceDialect,
21951 >,
21952 offset: usize,
21953 mut depth: fidl::encoding::Depth,
21954 ) -> fidl::Result<()> {
21955 decoder.debug_check_bounds::<Self>(offset);
21956 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
21957 None => return Err(fidl::Error::NotNullable),
21958 Some(len) => len,
21959 };
21960 // Calling decoder.out_of_line_offset(0) is not allowed.
21961 if len == 0 {
21962 return Ok(());
21963 };
21964 depth.increment()?;
21965 let envelope_size = 8;
21966 let bytes_len = len * envelope_size;
21967 let offset = decoder.out_of_line_offset(bytes_len)?;
21968 // Decode the envelope for each type.
21969 let mut _next_ordinal_to_read = 0;
21970 let mut next_offset = offset;
21971 let end_offset = offset + bytes_len;
21972 _next_ordinal_to_read += 1;
21973 if next_offset >= end_offset {
21974 return Ok(());
21975 }
21976
21977 // Decode unknown envelopes for gaps in ordinals.
21978 while _next_ordinal_to_read < 1 {
21979 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21980 _next_ordinal_to_read += 1;
21981 next_offset += envelope_size;
21982 }
21983
21984 let next_out_of_line = decoder.next_out_of_line();
21985 let handles_before = decoder.remaining_handles();
21986 if let Some((inlined, num_bytes, num_handles)) =
21987 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21988 {
21989 let member_inline_size = <fidl::encoding::HandleType<
21990 fidl::EventPair,
21991 { fidl::ObjectType::EVENTPAIR.into_raw() },
21992 2147483648,
21993 > as fidl::encoding::TypeMarker>::inline_size(
21994 decoder.context
21995 );
21996 if inlined != (member_inline_size <= 4) {
21997 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21998 }
21999 let inner_offset;
22000 let mut inner_depth = depth.clone();
22001 if inlined {
22002 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22003 inner_offset = next_offset;
22004 } else {
22005 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22006 inner_depth.increment()?;
22007 }
22008 let val_ref =
22009 self.server_end.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
22010 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
22011 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22012 {
22013 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22014 }
22015 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22016 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22017 }
22018 }
22019
22020 next_offset += envelope_size;
22021
22022 // Decode the remaining unknown envelopes.
22023 while next_offset < end_offset {
22024 _next_ordinal_to_read += 1;
22025 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22026 next_offset += envelope_size;
22027 }
22028
22029 Ok(())
22030 }
22031 }
22032
22033 impl NodeIsAlternateForRequest {
22034 #[inline(always)]
22035 fn max_ordinal_present(&self) -> u64 {
22036 if let Some(_) = self.node_ref {
22037 return 1;
22038 }
22039 0
22040 }
22041 }
22042
22043 impl fidl::encoding::ResourceTypeMarker for NodeIsAlternateForRequest {
22044 type Borrowed<'a> = &'a mut Self;
22045 fn take_or_borrow<'a>(
22046 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
22047 ) -> Self::Borrowed<'a> {
22048 value
22049 }
22050 }
22051
22052 unsafe impl fidl::encoding::TypeMarker for NodeIsAlternateForRequest {
22053 type Owned = Self;
22054
22055 #[inline(always)]
22056 fn inline_align(_context: fidl::encoding::Context) -> usize {
22057 8
22058 }
22059
22060 #[inline(always)]
22061 fn inline_size(_context: fidl::encoding::Context) -> usize {
22062 16
22063 }
22064 }
22065
22066 unsafe impl
22067 fidl::encoding::Encode<
22068 NodeIsAlternateForRequest,
22069 fidl::encoding::DefaultFuchsiaResourceDialect,
22070 > for &mut NodeIsAlternateForRequest
22071 {
22072 unsafe fn encode(
22073 self,
22074 encoder: &mut fidl::encoding::Encoder<
22075 '_,
22076 fidl::encoding::DefaultFuchsiaResourceDialect,
22077 >,
22078 offset: usize,
22079 mut depth: fidl::encoding::Depth,
22080 ) -> fidl::Result<()> {
22081 encoder.debug_check_bounds::<NodeIsAlternateForRequest>(offset);
22082 // Vector header
22083 let max_ordinal: u64 = self.max_ordinal_present();
22084 encoder.write_num(max_ordinal, offset);
22085 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
22086 // Calling encoder.out_of_line_offset(0) is not allowed.
22087 if max_ordinal == 0 {
22088 return Ok(());
22089 }
22090 depth.increment()?;
22091 let envelope_size = 8;
22092 let bytes_len = max_ordinal as usize * envelope_size;
22093 #[allow(unused_variables)]
22094 let offset = encoder.out_of_line_offset(bytes_len);
22095 let mut _prev_end_offset: usize = 0;
22096 if 1 > max_ordinal {
22097 return Ok(());
22098 }
22099
22100 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22101 // are envelope_size bytes.
22102 let cur_offset: usize = (1 - 1) * envelope_size;
22103
22104 // Zero reserved fields.
22105 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22106
22107 // Safety:
22108 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22109 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22110 // envelope_size bytes, there is always sufficient room.
22111 fidl::encoding::encode_in_envelope_optional::<
22112 fidl::encoding::HandleType<
22113 fidl::Event,
22114 { fidl::ObjectType::EVENT.into_raw() },
22115 2147483648,
22116 >,
22117 fidl::encoding::DefaultFuchsiaResourceDialect,
22118 >(
22119 self.node_ref.as_mut().map(
22120 <fidl::encoding::HandleType<
22121 fidl::Event,
22122 { fidl::ObjectType::EVENT.into_raw() },
22123 2147483648,
22124 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
22125 ),
22126 encoder,
22127 offset + cur_offset,
22128 depth,
22129 )?;
22130
22131 _prev_end_offset = cur_offset + envelope_size;
22132
22133 Ok(())
22134 }
22135 }
22136
22137 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
22138 for NodeIsAlternateForRequest
22139 {
22140 #[inline(always)]
22141 fn new_empty() -> Self {
22142 Self::default()
22143 }
22144
22145 unsafe fn decode(
22146 &mut self,
22147 decoder: &mut fidl::encoding::Decoder<
22148 '_,
22149 fidl::encoding::DefaultFuchsiaResourceDialect,
22150 >,
22151 offset: usize,
22152 mut depth: fidl::encoding::Depth,
22153 ) -> fidl::Result<()> {
22154 decoder.debug_check_bounds::<Self>(offset);
22155 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
22156 None => return Err(fidl::Error::NotNullable),
22157 Some(len) => len,
22158 };
22159 // Calling decoder.out_of_line_offset(0) is not allowed.
22160 if len == 0 {
22161 return Ok(());
22162 };
22163 depth.increment()?;
22164 let envelope_size = 8;
22165 let bytes_len = len * envelope_size;
22166 let offset = decoder.out_of_line_offset(bytes_len)?;
22167 // Decode the envelope for each type.
22168 let mut _next_ordinal_to_read = 0;
22169 let mut next_offset = offset;
22170 let end_offset = offset + bytes_len;
22171 _next_ordinal_to_read += 1;
22172 if next_offset >= end_offset {
22173 return Ok(());
22174 }
22175
22176 // Decode unknown envelopes for gaps in ordinals.
22177 while _next_ordinal_to_read < 1 {
22178 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22179 _next_ordinal_to_read += 1;
22180 next_offset += envelope_size;
22181 }
22182
22183 let next_out_of_line = decoder.next_out_of_line();
22184 let handles_before = decoder.remaining_handles();
22185 if let Some((inlined, num_bytes, num_handles)) =
22186 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22187 {
22188 let member_inline_size = <fidl::encoding::HandleType<
22189 fidl::Event,
22190 { fidl::ObjectType::EVENT.into_raw() },
22191 2147483648,
22192 > as fidl::encoding::TypeMarker>::inline_size(
22193 decoder.context
22194 );
22195 if inlined != (member_inline_size <= 4) {
22196 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22197 }
22198 let inner_offset;
22199 let mut inner_depth = depth.clone();
22200 if inlined {
22201 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22202 inner_offset = next_offset;
22203 } else {
22204 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22205 inner_depth.increment()?;
22206 }
22207 let val_ref =
22208 self.node_ref.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
22209 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
22210 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22211 {
22212 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22213 }
22214 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22215 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22216 }
22217 }
22218
22219 next_offset += envelope_size;
22220
22221 // Decode the remaining unknown envelopes.
22222 while next_offset < end_offset {
22223 _next_ordinal_to_read += 1;
22224 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22225 next_offset += envelope_size;
22226 }
22227
22228 Ok(())
22229 }
22230 }
22231
22232 impl NodeSetWeakOkRequest {
22233 #[inline(always)]
22234 fn max_ordinal_present(&self) -> u64 {
22235 if let Some(_) = self.for_child_nodes_also {
22236 return 1;
22237 }
22238 0
22239 }
22240 }
22241
22242 impl fidl::encoding::ResourceTypeMarker for NodeSetWeakOkRequest {
22243 type Borrowed<'a> = &'a mut Self;
22244 fn take_or_borrow<'a>(
22245 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
22246 ) -> Self::Borrowed<'a> {
22247 value
22248 }
22249 }
22250
22251 unsafe impl fidl::encoding::TypeMarker for NodeSetWeakOkRequest {
22252 type Owned = Self;
22253
22254 #[inline(always)]
22255 fn inline_align(_context: fidl::encoding::Context) -> usize {
22256 8
22257 }
22258
22259 #[inline(always)]
22260 fn inline_size(_context: fidl::encoding::Context) -> usize {
22261 16
22262 }
22263 }
22264
22265 unsafe impl
22266 fidl::encoding::Encode<NodeSetWeakOkRequest, fidl::encoding::DefaultFuchsiaResourceDialect>
22267 for &mut NodeSetWeakOkRequest
22268 {
22269 unsafe fn encode(
22270 self,
22271 encoder: &mut fidl::encoding::Encoder<
22272 '_,
22273 fidl::encoding::DefaultFuchsiaResourceDialect,
22274 >,
22275 offset: usize,
22276 mut depth: fidl::encoding::Depth,
22277 ) -> fidl::Result<()> {
22278 encoder.debug_check_bounds::<NodeSetWeakOkRequest>(offset);
22279 // Vector header
22280 let max_ordinal: u64 = self.max_ordinal_present();
22281 encoder.write_num(max_ordinal, offset);
22282 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
22283 // Calling encoder.out_of_line_offset(0) is not allowed.
22284 if max_ordinal == 0 {
22285 return Ok(());
22286 }
22287 depth.increment()?;
22288 let envelope_size = 8;
22289 let bytes_len = max_ordinal as usize * envelope_size;
22290 #[allow(unused_variables)]
22291 let offset = encoder.out_of_line_offset(bytes_len);
22292 let mut _prev_end_offset: usize = 0;
22293 if 1 > max_ordinal {
22294 return Ok(());
22295 }
22296
22297 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22298 // are envelope_size bytes.
22299 let cur_offset: usize = (1 - 1) * envelope_size;
22300
22301 // Zero reserved fields.
22302 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22303
22304 // Safety:
22305 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22306 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22307 // envelope_size bytes, there is always sufficient room.
22308 fidl::encoding::encode_in_envelope_optional::<
22309 bool,
22310 fidl::encoding::DefaultFuchsiaResourceDialect,
22311 >(
22312 self.for_child_nodes_also
22313 .as_ref()
22314 .map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
22315 encoder,
22316 offset + cur_offset,
22317 depth,
22318 )?;
22319
22320 _prev_end_offset = cur_offset + envelope_size;
22321
22322 Ok(())
22323 }
22324 }
22325
22326 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
22327 for NodeSetWeakOkRequest
22328 {
22329 #[inline(always)]
22330 fn new_empty() -> Self {
22331 Self::default()
22332 }
22333
22334 unsafe fn decode(
22335 &mut self,
22336 decoder: &mut fidl::encoding::Decoder<
22337 '_,
22338 fidl::encoding::DefaultFuchsiaResourceDialect,
22339 >,
22340 offset: usize,
22341 mut depth: fidl::encoding::Depth,
22342 ) -> fidl::Result<()> {
22343 decoder.debug_check_bounds::<Self>(offset);
22344 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
22345 None => return Err(fidl::Error::NotNullable),
22346 Some(len) => len,
22347 };
22348 // Calling decoder.out_of_line_offset(0) is not allowed.
22349 if len == 0 {
22350 return Ok(());
22351 };
22352 depth.increment()?;
22353 let envelope_size = 8;
22354 let bytes_len = len * envelope_size;
22355 let offset = decoder.out_of_line_offset(bytes_len)?;
22356 // Decode the envelope for each type.
22357 let mut _next_ordinal_to_read = 0;
22358 let mut next_offset = offset;
22359 let end_offset = offset + bytes_len;
22360 _next_ordinal_to_read += 1;
22361 if next_offset >= end_offset {
22362 return Ok(());
22363 }
22364
22365 // Decode unknown envelopes for gaps in ordinals.
22366 while _next_ordinal_to_read < 1 {
22367 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22368 _next_ordinal_to_read += 1;
22369 next_offset += envelope_size;
22370 }
22371
22372 let next_out_of_line = decoder.next_out_of_line();
22373 let handles_before = decoder.remaining_handles();
22374 if let Some((inlined, num_bytes, num_handles)) =
22375 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22376 {
22377 let member_inline_size =
22378 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
22379 if inlined != (member_inline_size <= 4) {
22380 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22381 }
22382 let inner_offset;
22383 let mut inner_depth = depth.clone();
22384 if inlined {
22385 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22386 inner_offset = next_offset;
22387 } else {
22388 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22389 inner_depth.increment()?;
22390 }
22391 let val_ref = self.for_child_nodes_also.get_or_insert_with(|| {
22392 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
22393 });
22394 fidl::decode!(
22395 bool,
22396 fidl::encoding::DefaultFuchsiaResourceDialect,
22397 val_ref,
22398 decoder,
22399 inner_offset,
22400 inner_depth
22401 )?;
22402 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22403 {
22404 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22405 }
22406 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22407 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22408 }
22409 }
22410
22411 next_offset += envelope_size;
22412
22413 // Decode the remaining unknown envelopes.
22414 while next_offset < end_offset {
22415 _next_ordinal_to_read += 1;
22416 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22417 next_offset += envelope_size;
22418 }
22419
22420 Ok(())
22421 }
22422 }
22423
22424 impl NodeGetNodeRefResponse {
22425 #[inline(always)]
22426 fn max_ordinal_present(&self) -> u64 {
22427 if let Some(_) = self.node_ref {
22428 return 1;
22429 }
22430 0
22431 }
22432 }
22433
22434 impl fidl::encoding::ResourceTypeMarker for NodeGetNodeRefResponse {
22435 type Borrowed<'a> = &'a mut Self;
22436 fn take_or_borrow<'a>(
22437 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
22438 ) -> Self::Borrowed<'a> {
22439 value
22440 }
22441 }
22442
22443 unsafe impl fidl::encoding::TypeMarker for NodeGetNodeRefResponse {
22444 type Owned = Self;
22445
22446 #[inline(always)]
22447 fn inline_align(_context: fidl::encoding::Context) -> usize {
22448 8
22449 }
22450
22451 #[inline(always)]
22452 fn inline_size(_context: fidl::encoding::Context) -> usize {
22453 16
22454 }
22455 }
22456
22457 unsafe impl
22458 fidl::encoding::Encode<
22459 NodeGetNodeRefResponse,
22460 fidl::encoding::DefaultFuchsiaResourceDialect,
22461 > for &mut NodeGetNodeRefResponse
22462 {
22463 unsafe fn encode(
22464 self,
22465 encoder: &mut fidl::encoding::Encoder<
22466 '_,
22467 fidl::encoding::DefaultFuchsiaResourceDialect,
22468 >,
22469 offset: usize,
22470 mut depth: fidl::encoding::Depth,
22471 ) -> fidl::Result<()> {
22472 encoder.debug_check_bounds::<NodeGetNodeRefResponse>(offset);
22473 // Vector header
22474 let max_ordinal: u64 = self.max_ordinal_present();
22475 encoder.write_num(max_ordinal, offset);
22476 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
22477 // Calling encoder.out_of_line_offset(0) is not allowed.
22478 if max_ordinal == 0 {
22479 return Ok(());
22480 }
22481 depth.increment()?;
22482 let envelope_size = 8;
22483 let bytes_len = max_ordinal as usize * envelope_size;
22484 #[allow(unused_variables)]
22485 let offset = encoder.out_of_line_offset(bytes_len);
22486 let mut _prev_end_offset: usize = 0;
22487 if 1 > max_ordinal {
22488 return Ok(());
22489 }
22490
22491 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22492 // are envelope_size bytes.
22493 let cur_offset: usize = (1 - 1) * envelope_size;
22494
22495 // Zero reserved fields.
22496 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22497
22498 // Safety:
22499 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22500 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22501 // envelope_size bytes, there is always sufficient room.
22502 fidl::encoding::encode_in_envelope_optional::<
22503 fidl::encoding::HandleType<
22504 fidl::Event,
22505 { fidl::ObjectType::EVENT.into_raw() },
22506 2147483648,
22507 >,
22508 fidl::encoding::DefaultFuchsiaResourceDialect,
22509 >(
22510 self.node_ref.as_mut().map(
22511 <fidl::encoding::HandleType<
22512 fidl::Event,
22513 { fidl::ObjectType::EVENT.into_raw() },
22514 2147483648,
22515 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
22516 ),
22517 encoder,
22518 offset + cur_offset,
22519 depth,
22520 )?;
22521
22522 _prev_end_offset = cur_offset + envelope_size;
22523
22524 Ok(())
22525 }
22526 }
22527
22528 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
22529 for NodeGetNodeRefResponse
22530 {
22531 #[inline(always)]
22532 fn new_empty() -> Self {
22533 Self::default()
22534 }
22535
22536 unsafe fn decode(
22537 &mut self,
22538 decoder: &mut fidl::encoding::Decoder<
22539 '_,
22540 fidl::encoding::DefaultFuchsiaResourceDialect,
22541 >,
22542 offset: usize,
22543 mut depth: fidl::encoding::Depth,
22544 ) -> fidl::Result<()> {
22545 decoder.debug_check_bounds::<Self>(offset);
22546 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
22547 None => return Err(fidl::Error::NotNullable),
22548 Some(len) => len,
22549 };
22550 // Calling decoder.out_of_line_offset(0) is not allowed.
22551 if len == 0 {
22552 return Ok(());
22553 };
22554 depth.increment()?;
22555 let envelope_size = 8;
22556 let bytes_len = len * envelope_size;
22557 let offset = decoder.out_of_line_offset(bytes_len)?;
22558 // Decode the envelope for each type.
22559 let mut _next_ordinal_to_read = 0;
22560 let mut next_offset = offset;
22561 let end_offset = offset + bytes_len;
22562 _next_ordinal_to_read += 1;
22563 if next_offset >= end_offset {
22564 return Ok(());
22565 }
22566
22567 // Decode unknown envelopes for gaps in ordinals.
22568 while _next_ordinal_to_read < 1 {
22569 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22570 _next_ordinal_to_read += 1;
22571 next_offset += envelope_size;
22572 }
22573
22574 let next_out_of_line = decoder.next_out_of_line();
22575 let handles_before = decoder.remaining_handles();
22576 if let Some((inlined, num_bytes, num_handles)) =
22577 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22578 {
22579 let member_inline_size = <fidl::encoding::HandleType<
22580 fidl::Event,
22581 { fidl::ObjectType::EVENT.into_raw() },
22582 2147483648,
22583 > as fidl::encoding::TypeMarker>::inline_size(
22584 decoder.context
22585 );
22586 if inlined != (member_inline_size <= 4) {
22587 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22588 }
22589 let inner_offset;
22590 let mut inner_depth = depth.clone();
22591 if inlined {
22592 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22593 inner_offset = next_offset;
22594 } else {
22595 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22596 inner_depth.increment()?;
22597 }
22598 let val_ref =
22599 self.node_ref.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
22600 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
22601 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22602 {
22603 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22604 }
22605 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22606 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22607 }
22608 }
22609
22610 next_offset += envelope_size;
22611
22612 // Decode the remaining unknown envelopes.
22613 while next_offset < end_offset {
22614 _next_ordinal_to_read += 1;
22615 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22616 next_offset += envelope_size;
22617 }
22618
22619 Ok(())
22620 }
22621 }
22622
22623 impl VmoBuffer {
22624 #[inline(always)]
22625 fn max_ordinal_present(&self) -> u64 {
22626 if let Some(_) = self.close_weak_asap {
22627 return 3;
22628 }
22629 if let Some(_) = self.vmo_usable_start {
22630 return 2;
22631 }
22632 if let Some(_) = self.vmo {
22633 return 1;
22634 }
22635 0
22636 }
22637 }
22638
22639 impl fidl::encoding::ResourceTypeMarker for VmoBuffer {
22640 type Borrowed<'a> = &'a mut Self;
22641 fn take_or_borrow<'a>(
22642 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
22643 ) -> Self::Borrowed<'a> {
22644 value
22645 }
22646 }
22647
22648 unsafe impl fidl::encoding::TypeMarker for VmoBuffer {
22649 type Owned = Self;
22650
22651 #[inline(always)]
22652 fn inline_align(_context: fidl::encoding::Context) -> usize {
22653 8
22654 }
22655
22656 #[inline(always)]
22657 fn inline_size(_context: fidl::encoding::Context) -> usize {
22658 16
22659 }
22660 }
22661
22662 unsafe impl fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>
22663 for &mut VmoBuffer
22664 {
22665 unsafe fn encode(
22666 self,
22667 encoder: &mut fidl::encoding::Encoder<
22668 '_,
22669 fidl::encoding::DefaultFuchsiaResourceDialect,
22670 >,
22671 offset: usize,
22672 mut depth: fidl::encoding::Depth,
22673 ) -> fidl::Result<()> {
22674 encoder.debug_check_bounds::<VmoBuffer>(offset);
22675 // Vector header
22676 let max_ordinal: u64 = self.max_ordinal_present();
22677 encoder.write_num(max_ordinal, offset);
22678 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
22679 // Calling encoder.out_of_line_offset(0) is not allowed.
22680 if max_ordinal == 0 {
22681 return Ok(());
22682 }
22683 depth.increment()?;
22684 let envelope_size = 8;
22685 let bytes_len = max_ordinal as usize * envelope_size;
22686 #[allow(unused_variables)]
22687 let offset = encoder.out_of_line_offset(bytes_len);
22688 let mut _prev_end_offset: usize = 0;
22689 if 1 > max_ordinal {
22690 return Ok(());
22691 }
22692
22693 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22694 // are envelope_size bytes.
22695 let cur_offset: usize = (1 - 1) * envelope_size;
22696
22697 // Zero reserved fields.
22698 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22699
22700 // Safety:
22701 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22702 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22703 // envelope_size bytes, there is always sufficient room.
22704 fidl::encoding::encode_in_envelope_optional::<
22705 fidl::encoding::HandleType<
22706 fidl::Vmo,
22707 { fidl::ObjectType::VMO.into_raw() },
22708 2147483648,
22709 >,
22710 fidl::encoding::DefaultFuchsiaResourceDialect,
22711 >(
22712 self.vmo.as_mut().map(
22713 <fidl::encoding::HandleType<
22714 fidl::Vmo,
22715 { fidl::ObjectType::VMO.into_raw() },
22716 2147483648,
22717 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
22718 ),
22719 encoder,
22720 offset + cur_offset,
22721 depth,
22722 )?;
22723
22724 _prev_end_offset = cur_offset + envelope_size;
22725 if 2 > max_ordinal {
22726 return Ok(());
22727 }
22728
22729 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22730 // are envelope_size bytes.
22731 let cur_offset: usize = (2 - 1) * envelope_size;
22732
22733 // Zero reserved fields.
22734 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22735
22736 // Safety:
22737 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22738 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22739 // envelope_size bytes, there is always sufficient room.
22740 fidl::encoding::encode_in_envelope_optional::<
22741 u64,
22742 fidl::encoding::DefaultFuchsiaResourceDialect,
22743 >(
22744 self.vmo_usable_start
22745 .as_ref()
22746 .map(<u64 as fidl::encoding::ValueTypeMarker>::borrow),
22747 encoder,
22748 offset + cur_offset,
22749 depth,
22750 )?;
22751
22752 _prev_end_offset = cur_offset + envelope_size;
22753 if 3 > max_ordinal {
22754 return Ok(());
22755 }
22756
22757 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22758 // are envelope_size bytes.
22759 let cur_offset: usize = (3 - 1) * envelope_size;
22760
22761 // Zero reserved fields.
22762 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22763
22764 // Safety:
22765 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22766 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22767 // envelope_size bytes, there is always sufficient room.
22768 fidl::encoding::encode_in_envelope_optional::<
22769 fidl::encoding::HandleType<
22770 fidl::EventPair,
22771 { fidl::ObjectType::EVENTPAIR.into_raw() },
22772 2147483648,
22773 >,
22774 fidl::encoding::DefaultFuchsiaResourceDialect,
22775 >(
22776 self.close_weak_asap.as_mut().map(
22777 <fidl::encoding::HandleType<
22778 fidl::EventPair,
22779 { fidl::ObjectType::EVENTPAIR.into_raw() },
22780 2147483648,
22781 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
22782 ),
22783 encoder,
22784 offset + cur_offset,
22785 depth,
22786 )?;
22787
22788 _prev_end_offset = cur_offset + envelope_size;
22789
22790 Ok(())
22791 }
22792 }
22793
22794 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect> for VmoBuffer {
22795 #[inline(always)]
22796 fn new_empty() -> Self {
22797 Self::default()
22798 }
22799
22800 unsafe fn decode(
22801 &mut self,
22802 decoder: &mut fidl::encoding::Decoder<
22803 '_,
22804 fidl::encoding::DefaultFuchsiaResourceDialect,
22805 >,
22806 offset: usize,
22807 mut depth: fidl::encoding::Depth,
22808 ) -> fidl::Result<()> {
22809 decoder.debug_check_bounds::<Self>(offset);
22810 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
22811 None => return Err(fidl::Error::NotNullable),
22812 Some(len) => len,
22813 };
22814 // Calling decoder.out_of_line_offset(0) is not allowed.
22815 if len == 0 {
22816 return Ok(());
22817 };
22818 depth.increment()?;
22819 let envelope_size = 8;
22820 let bytes_len = len * envelope_size;
22821 let offset = decoder.out_of_line_offset(bytes_len)?;
22822 // Decode the envelope for each type.
22823 let mut _next_ordinal_to_read = 0;
22824 let mut next_offset = offset;
22825 let end_offset = offset + bytes_len;
22826 _next_ordinal_to_read += 1;
22827 if next_offset >= end_offset {
22828 return Ok(());
22829 }
22830
22831 // Decode unknown envelopes for gaps in ordinals.
22832 while _next_ordinal_to_read < 1 {
22833 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22834 _next_ordinal_to_read += 1;
22835 next_offset += envelope_size;
22836 }
22837
22838 let next_out_of_line = decoder.next_out_of_line();
22839 let handles_before = decoder.remaining_handles();
22840 if let Some((inlined, num_bytes, num_handles)) =
22841 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22842 {
22843 let member_inline_size = <fidl::encoding::HandleType<
22844 fidl::Vmo,
22845 { fidl::ObjectType::VMO.into_raw() },
22846 2147483648,
22847 > as fidl::encoding::TypeMarker>::inline_size(
22848 decoder.context
22849 );
22850 if inlined != (member_inline_size <= 4) {
22851 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22852 }
22853 let inner_offset;
22854 let mut inner_depth = depth.clone();
22855 if inlined {
22856 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22857 inner_offset = next_offset;
22858 } else {
22859 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22860 inner_depth.increment()?;
22861 }
22862 let val_ref =
22863 self.vmo.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
22864 fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
22865 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22866 {
22867 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22868 }
22869 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22870 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22871 }
22872 }
22873
22874 next_offset += envelope_size;
22875 _next_ordinal_to_read += 1;
22876 if next_offset >= end_offset {
22877 return Ok(());
22878 }
22879
22880 // Decode unknown envelopes for gaps in ordinals.
22881 while _next_ordinal_to_read < 2 {
22882 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22883 _next_ordinal_to_read += 1;
22884 next_offset += envelope_size;
22885 }
22886
22887 let next_out_of_line = decoder.next_out_of_line();
22888 let handles_before = decoder.remaining_handles();
22889 if let Some((inlined, num_bytes, num_handles)) =
22890 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22891 {
22892 let member_inline_size =
22893 <u64 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
22894 if inlined != (member_inline_size <= 4) {
22895 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22896 }
22897 let inner_offset;
22898 let mut inner_depth = depth.clone();
22899 if inlined {
22900 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22901 inner_offset = next_offset;
22902 } else {
22903 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22904 inner_depth.increment()?;
22905 }
22906 let val_ref = self.vmo_usable_start.get_or_insert_with(|| {
22907 fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect)
22908 });
22909 fidl::decode!(
22910 u64,
22911 fidl::encoding::DefaultFuchsiaResourceDialect,
22912 val_ref,
22913 decoder,
22914 inner_offset,
22915 inner_depth
22916 )?;
22917 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22918 {
22919 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22920 }
22921 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22922 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22923 }
22924 }
22925
22926 next_offset += envelope_size;
22927 _next_ordinal_to_read += 1;
22928 if next_offset >= end_offset {
22929 return Ok(());
22930 }
22931
22932 // Decode unknown envelopes for gaps in ordinals.
22933 while _next_ordinal_to_read < 3 {
22934 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22935 _next_ordinal_to_read += 1;
22936 next_offset += envelope_size;
22937 }
22938
22939 let next_out_of_line = decoder.next_out_of_line();
22940 let handles_before = decoder.remaining_handles();
22941 if let Some((inlined, num_bytes, num_handles)) =
22942 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22943 {
22944 let member_inline_size = <fidl::encoding::HandleType<
22945 fidl::EventPair,
22946 { fidl::ObjectType::EVENTPAIR.into_raw() },
22947 2147483648,
22948 > as fidl::encoding::TypeMarker>::inline_size(
22949 decoder.context
22950 );
22951 if inlined != (member_inline_size <= 4) {
22952 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22953 }
22954 let inner_offset;
22955 let mut inner_depth = depth.clone();
22956 if inlined {
22957 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22958 inner_offset = next_offset;
22959 } else {
22960 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22961 inner_depth.increment()?;
22962 }
22963 let val_ref =
22964 self.close_weak_asap.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
22965 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
22966 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22967 {
22968 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22969 }
22970 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22971 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22972 }
22973 }
22974
22975 next_offset += envelope_size;
22976
22977 // Decode the remaining unknown envelopes.
22978 while next_offset < end_offset {
22979 _next_ordinal_to_read += 1;
22980 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22981 next_offset += envelope_size;
22982 }
22983
22984 Ok(())
22985 }
22986 }
22987}