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 fidl::endpoints::ControlHandle for AllocatorControlHandle {
1904 fn shutdown(&self) {
1905 self.inner.shutdown()
1906 }
1907
1908 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
1909 self.inner.shutdown_with_epitaph(status)
1910 }
1911
1912 fn is_closed(&self) -> bool {
1913 self.inner.channel().is_closed()
1914 }
1915 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1916 self.inner.channel().on_closed()
1917 }
1918
1919 #[cfg(target_os = "fuchsia")]
1920 fn signal_peer(
1921 &self,
1922 clear_mask: zx::Signals,
1923 set_mask: zx::Signals,
1924 ) -> Result<(), zx_status::Status> {
1925 use fidl::Peered;
1926 self.inner.channel().signal_peer(clear_mask, set_mask)
1927 }
1928}
1929
1930impl AllocatorControlHandle {}
1931
1932#[must_use = "FIDL methods require a response to be sent"]
1933#[derive(Debug)]
1934pub struct AllocatorValidateBufferCollectionTokenResponder {
1935 control_handle: std::mem::ManuallyDrop<AllocatorControlHandle>,
1936 tx_id: u32,
1937}
1938
1939/// Set the the channel to be shutdown (see [`AllocatorControlHandle::shutdown`])
1940/// if the responder is dropped without sending a response, so that the client
1941/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1942impl std::ops::Drop for AllocatorValidateBufferCollectionTokenResponder {
1943 fn drop(&mut self) {
1944 self.control_handle.shutdown();
1945 // Safety: drops once, never accessed again
1946 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1947 }
1948}
1949
1950impl fidl::endpoints::Responder for AllocatorValidateBufferCollectionTokenResponder {
1951 type ControlHandle = AllocatorControlHandle;
1952
1953 fn control_handle(&self) -> &AllocatorControlHandle {
1954 &self.control_handle
1955 }
1956
1957 fn drop_without_shutdown(mut self) {
1958 // Safety: drops once, never accessed again due to mem::forget
1959 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1960 // Prevent Drop from running (which would shut down the channel)
1961 std::mem::forget(self);
1962 }
1963}
1964
1965impl AllocatorValidateBufferCollectionTokenResponder {
1966 /// Sends a response to the FIDL transaction.
1967 ///
1968 /// Sets the channel to shutdown if an error occurs.
1969 pub fn send(
1970 self,
1971 mut payload: &AllocatorValidateBufferCollectionTokenResponse,
1972 ) -> Result<(), fidl::Error> {
1973 let _result = self.send_raw(payload);
1974 if _result.is_err() {
1975 self.control_handle.shutdown();
1976 }
1977 self.drop_without_shutdown();
1978 _result
1979 }
1980
1981 /// Similar to "send" but does not shutdown the channel if an error occurs.
1982 pub fn send_no_shutdown_on_err(
1983 self,
1984 mut payload: &AllocatorValidateBufferCollectionTokenResponse,
1985 ) -> Result<(), fidl::Error> {
1986 let _result = self.send_raw(payload);
1987 self.drop_without_shutdown();
1988 _result
1989 }
1990
1991 fn send_raw(
1992 &self,
1993 mut payload: &AllocatorValidateBufferCollectionTokenResponse,
1994 ) -> Result<(), fidl::Error> {
1995 self.control_handle.inner.send::<fidl::encoding::FlexibleType<
1996 AllocatorValidateBufferCollectionTokenResponse,
1997 >>(
1998 fidl::encoding::Flexible::new(payload),
1999 self.tx_id,
2000 0x4c5ee91b02a7e68d,
2001 fidl::encoding::DynamicFlags::FLEXIBLE,
2002 )
2003 }
2004}
2005
2006#[must_use = "FIDL methods require a response to be sent"]
2007#[derive(Debug)]
2008pub struct AllocatorGetVmoInfoResponder {
2009 control_handle: std::mem::ManuallyDrop<AllocatorControlHandle>,
2010 tx_id: u32,
2011}
2012
2013/// Set the the channel to be shutdown (see [`AllocatorControlHandle::shutdown`])
2014/// if the responder is dropped without sending a response, so that the client
2015/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
2016impl std::ops::Drop for AllocatorGetVmoInfoResponder {
2017 fn drop(&mut self) {
2018 self.control_handle.shutdown();
2019 // Safety: drops once, never accessed again
2020 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
2021 }
2022}
2023
2024impl fidl::endpoints::Responder for AllocatorGetVmoInfoResponder {
2025 type ControlHandle = AllocatorControlHandle;
2026
2027 fn control_handle(&self) -> &AllocatorControlHandle {
2028 &self.control_handle
2029 }
2030
2031 fn drop_without_shutdown(mut self) {
2032 // Safety: drops once, never accessed again due to mem::forget
2033 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
2034 // Prevent Drop from running (which would shut down the channel)
2035 std::mem::forget(self);
2036 }
2037}
2038
2039impl AllocatorGetVmoInfoResponder {
2040 /// Sends a response to the FIDL transaction.
2041 ///
2042 /// Sets the channel to shutdown if an error occurs.
2043 pub fn send(
2044 self,
2045 mut result: Result<AllocatorGetVmoInfoResponse, Error>,
2046 ) -> Result<(), fidl::Error> {
2047 let _result = self.send_raw(result);
2048 if _result.is_err() {
2049 self.control_handle.shutdown();
2050 }
2051 self.drop_without_shutdown();
2052 _result
2053 }
2054
2055 /// Similar to "send" but does not shutdown the channel if an error occurs.
2056 pub fn send_no_shutdown_on_err(
2057 self,
2058 mut result: Result<AllocatorGetVmoInfoResponse, Error>,
2059 ) -> Result<(), fidl::Error> {
2060 let _result = self.send_raw(result);
2061 self.drop_without_shutdown();
2062 _result
2063 }
2064
2065 fn send_raw(
2066 &self,
2067 mut result: Result<AllocatorGetVmoInfoResponse, Error>,
2068 ) -> Result<(), fidl::Error> {
2069 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
2070 AllocatorGetVmoInfoResponse,
2071 Error,
2072 >>(
2073 fidl::encoding::FlexibleResult::new(result.as_mut().map_err(|e| *e)),
2074 self.tx_id,
2075 0x21a881120aa0ddf9,
2076 fidl::encoding::DynamicFlags::FLEXIBLE,
2077 )
2078 }
2079}
2080
2081#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
2082pub struct BufferCollectionMarker;
2083
2084impl fidl::endpoints::ProtocolMarker for BufferCollectionMarker {
2085 type Proxy = BufferCollectionProxy;
2086 type RequestStream = BufferCollectionRequestStream;
2087 #[cfg(target_os = "fuchsia")]
2088 type SynchronousProxy = BufferCollectionSynchronousProxy;
2089
2090 const DEBUG_NAME: &'static str = "(anonymous) BufferCollection";
2091}
2092pub type BufferCollectionWaitForAllBuffersAllocatedResult =
2093 Result<BufferCollectionWaitForAllBuffersAllocatedResponse, Error>;
2094pub type BufferCollectionCheckAllBuffersAllocatedResult = Result<(), Error>;
2095
2096pub trait BufferCollectionProxyInterface: Send + Sync {
2097 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
2098 fn r#sync(&self) -> Self::SyncResponseFut;
2099 fn r#release(&self) -> Result<(), fidl::Error>;
2100 fn r#set_name(&self, payload: &NodeSetNameRequest) -> Result<(), fidl::Error>;
2101 fn r#set_debug_client_info(
2102 &self,
2103 payload: &NodeSetDebugClientInfoRequest,
2104 ) -> Result<(), fidl::Error>;
2105 fn r#set_debug_timeout_log_deadline(
2106 &self,
2107 payload: &NodeSetDebugTimeoutLogDeadlineRequest,
2108 ) -> Result<(), fidl::Error>;
2109 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
2110 type GetNodeRefResponseFut: std::future::Future<Output = Result<NodeGetNodeRefResponse, fidl::Error>>
2111 + Send;
2112 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
2113 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
2114 + Send;
2115 fn r#is_alternate_for(
2116 &self,
2117 payload: NodeIsAlternateForRequest,
2118 ) -> Self::IsAlternateForResponseFut;
2119 type GetBufferCollectionIdResponseFut: std::future::Future<Output = Result<NodeGetBufferCollectionIdResponse, fidl::Error>>
2120 + Send;
2121 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut;
2122 fn r#set_weak(&self) -> Result<(), fidl::Error>;
2123 fn r#set_weak_ok(&self, payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error>;
2124 fn r#attach_node_tracking(
2125 &self,
2126 payload: NodeAttachNodeTrackingRequest,
2127 ) -> Result<(), fidl::Error>;
2128 fn r#set_constraints(
2129 &self,
2130 payload: BufferCollectionSetConstraintsRequest,
2131 ) -> Result<(), fidl::Error>;
2132 type WaitForAllBuffersAllocatedResponseFut: std::future::Future<
2133 Output = Result<BufferCollectionWaitForAllBuffersAllocatedResult, fidl::Error>,
2134 > + Send;
2135 fn r#wait_for_all_buffers_allocated(&self) -> Self::WaitForAllBuffersAllocatedResponseFut;
2136 type CheckAllBuffersAllocatedResponseFut: std::future::Future<
2137 Output = Result<BufferCollectionCheckAllBuffersAllocatedResult, fidl::Error>,
2138 > + Send;
2139 fn r#check_all_buffers_allocated(&self) -> Self::CheckAllBuffersAllocatedResponseFut;
2140 fn r#attach_token(
2141 &self,
2142 payload: BufferCollectionAttachTokenRequest,
2143 ) -> Result<(), fidl::Error>;
2144 fn r#attach_lifetime_tracking(
2145 &self,
2146 payload: BufferCollectionAttachLifetimeTrackingRequest,
2147 ) -> Result<(), fidl::Error>;
2148}
2149#[derive(Debug)]
2150#[cfg(target_os = "fuchsia")]
2151pub struct BufferCollectionSynchronousProxy {
2152 client: fidl::client::sync::Client,
2153}
2154
2155#[cfg(target_os = "fuchsia")]
2156impl fidl::endpoints::SynchronousProxy for BufferCollectionSynchronousProxy {
2157 type Proxy = BufferCollectionProxy;
2158 type Protocol = BufferCollectionMarker;
2159
2160 fn from_channel(inner: fidl::Channel) -> Self {
2161 Self::new(inner)
2162 }
2163
2164 fn into_channel(self) -> fidl::Channel {
2165 self.client.into_channel()
2166 }
2167
2168 fn as_channel(&self) -> &fidl::Channel {
2169 self.client.as_channel()
2170 }
2171}
2172
2173#[cfg(target_os = "fuchsia")]
2174impl BufferCollectionSynchronousProxy {
2175 pub fn new(channel: fidl::Channel) -> Self {
2176 Self { client: fidl::client::sync::Client::new(channel) }
2177 }
2178
2179 pub fn into_channel(self) -> fidl::Channel {
2180 self.client.into_channel()
2181 }
2182
2183 /// Waits until an event arrives and returns it. It is safe for other
2184 /// threads to make concurrent requests while waiting for an event.
2185 pub fn wait_for_event(
2186 &self,
2187 deadline: zx::MonotonicInstant,
2188 ) -> Result<BufferCollectionEvent, fidl::Error> {
2189 BufferCollectionEvent::decode(
2190 self.client.wait_for_event::<BufferCollectionMarker>(deadline)?,
2191 )
2192 }
2193
2194 /// Ensure that previous messages have been received server side. This is
2195 /// particularly useful after previous messages that created new tokens,
2196 /// because a token must be known to the sysmem server before sending the
2197 /// token to another participant.
2198 ///
2199 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
2200 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
2201 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
2202 /// to mitigate the possibility of a hostile/fake
2203 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
2204 /// Another way is to pass the token to
2205 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
2206 /// the token as part of exchanging it for a
2207 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
2208 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
2209 /// of stalling.
2210 ///
2211 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
2212 /// and then starting and completing a `Sync`, it's then safe to send the
2213 /// `BufferCollectionToken` client ends to other participants knowing the
2214 /// server will recognize the tokens when they're sent by the other
2215 /// participants to sysmem in a
2216 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
2217 /// efficient way to create tokens while avoiding unnecessary round trips.
2218 ///
2219 /// Other options include waiting for each
2220 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
2221 /// individually (using separate call to `Sync` after each), or calling
2222 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
2223 /// converted to a `BufferCollection` via
2224 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
2225 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
2226 /// the sync step and can create multiple tokens at once.
2227 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
2228 let _response = self.client.send_query::<
2229 fidl::encoding::EmptyPayload,
2230 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
2231 BufferCollectionMarker,
2232 >(
2233 (),
2234 0x11ac2555cf575b54,
2235 fidl::encoding::DynamicFlags::FLEXIBLE,
2236 ___deadline,
2237 )?
2238 .into_result::<BufferCollectionMarker>("sync")?;
2239 Ok(_response)
2240 }
2241
2242 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
2243 ///
2244 /// Normally a participant will convert a `BufferCollectionToken` into a
2245 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
2246 /// `Release` via the token (and then close the channel immediately or
2247 /// shortly later in response to server closing the server end), which
2248 /// avoids causing buffer collection failure. Without a prior `Release`,
2249 /// closing the `BufferCollectionToken` client end will cause buffer
2250 /// collection failure.
2251 ///
2252 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
2253 ///
2254 /// By default the server handles unexpected closure of a
2255 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
2256 /// first) by failing the buffer collection. Partly this is to expedite
2257 /// closing VMO handles to reclaim memory when any participant fails. If a
2258 /// participant would like to cleanly close a `BufferCollection` without
2259 /// causing buffer collection failure, the participant can send `Release`
2260 /// before closing the `BufferCollection` client end. The `Release` can
2261 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
2262 /// buffer collection won't require constraints from this node in order to
2263 /// allocate. If after `SetConstraints`, the constraints are retained and
2264 /// aggregated, despite the lack of `BufferCollection` connection at the
2265 /// time of constraints aggregation.
2266 ///
2267 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
2268 ///
2269 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
2270 /// end (without `Release` first) will trigger failure of the buffer
2271 /// collection. To close a `BufferCollectionTokenGroup` channel without
2272 /// failing the buffer collection, ensure that AllChildrenPresent() has been
2273 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
2274 /// client end.
2275 ///
2276 /// If `Release` occurs before
2277 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
2278 /// buffer collection will fail (triggered by reception of `Release` without
2279 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
2280 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
2281 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
2282 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
2283 /// close requires `AllChildrenPresent` (if not already sent), then
2284 /// `Release`, then close client end.
2285 ///
2286 /// If `Release` occurs after `AllChildrenPresent`, the children and all
2287 /// their constraints remain intact (just as they would if the
2288 /// `BufferCollectionTokenGroup` channel had remained open), and the client
2289 /// end close doesn't trigger buffer collection failure.
2290 ///
2291 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
2292 ///
2293 /// For brevity, the per-channel-protocol paragraphs above ignore the
2294 /// separate failure domain created by
2295 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
2296 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
2297 /// unexpectedly closes (without `Release` first) and that client end is
2298 /// under a failure domain, instead of failing the whole buffer collection,
2299 /// the failure domain is failed, but the buffer collection itself is
2300 /// isolated from failure of the failure domain. Such failure domains can be
2301 /// nested, in which case only the inner-most failure domain in which the
2302 /// `Node` resides fails.
2303 pub fn r#release(&self) -> Result<(), fidl::Error> {
2304 self.client.send::<fidl::encoding::EmptyPayload>(
2305 (),
2306 0x6a5cae7d6d6e04c6,
2307 fidl::encoding::DynamicFlags::FLEXIBLE,
2308 )
2309 }
2310
2311 /// Set a name for VMOs in this buffer collection.
2312 ///
2313 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
2314 /// will be truncated to fit. The name of the vmo will be suffixed with the
2315 /// buffer index within the collection (if the suffix fits within
2316 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
2317 /// listed in the inspect data.
2318 ///
2319 /// The name only affects VMOs allocated after the name is set; this call
2320 /// does not rename existing VMOs. If multiple clients set different names
2321 /// then the larger priority value will win. Setting a new name with the
2322 /// same priority as a prior name doesn't change the name.
2323 ///
2324 /// All table fields are currently required.
2325 ///
2326 /// + request `priority` The name is only set if this is the first `SetName`
2327 /// or if `priority` is greater than any previous `priority` value in
2328 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
2329 /// + request `name` The name for VMOs created under this buffer collection.
2330 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
2331 self.client.send::<NodeSetNameRequest>(
2332 payload,
2333 0xb41f1624f48c1e9,
2334 fidl::encoding::DynamicFlags::FLEXIBLE,
2335 )
2336 }
2337
2338 /// Set information about the current client that can be used by sysmem to
2339 /// help diagnose leaking memory and allocation stalls waiting for a
2340 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
2341 ///
2342 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
2343 /// `Node`(s) derived from this `Node`, unless overriden by
2344 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
2345 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
2346 ///
2347 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
2348 /// `Allocator` is the most efficient way to ensure that all
2349 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
2350 /// set, and is also more efficient than separately sending the same debug
2351 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
2352 /// created [`fuchsia.sysmem2/Node`].
2353 ///
2354 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
2355 /// indicate which client is closing their channel first, leading to subtree
2356 /// failure (which can be normal if the purpose of the subtree is over, but
2357 /// if happening earlier than expected, the client-channel-specific name can
2358 /// help diagnose where the failure is first coming from, from sysmem's
2359 /// point of view).
2360 ///
2361 /// All table fields are currently required.
2362 ///
2363 /// + request `name` This can be an arbitrary string, but the current
2364 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
2365 /// + request `id` This can be an arbitrary id, but the current process ID
2366 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
2367 pub fn r#set_debug_client_info(
2368 &self,
2369 mut payload: &NodeSetDebugClientInfoRequest,
2370 ) -> Result<(), fidl::Error> {
2371 self.client.send::<NodeSetDebugClientInfoRequest>(
2372 payload,
2373 0x5cde8914608d99b1,
2374 fidl::encoding::DynamicFlags::FLEXIBLE,
2375 )
2376 }
2377
2378 /// Sysmem logs a warning if sysmem hasn't seen
2379 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
2380 /// within 5 seconds after creation of a new collection.
2381 ///
2382 /// Clients can call this method to change when the log is printed. If
2383 /// multiple client set the deadline, it's unspecified which deadline will
2384 /// take effect.
2385 ///
2386 /// In most cases the default works well.
2387 ///
2388 /// All table fields are currently required.
2389 ///
2390 /// + request `deadline` The time at which sysmem will start trying to log
2391 /// the warning, unless all constraints are with sysmem by then.
2392 pub fn r#set_debug_timeout_log_deadline(
2393 &self,
2394 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
2395 ) -> Result<(), fidl::Error> {
2396 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
2397 payload,
2398 0x716b0af13d5c0806,
2399 fidl::encoding::DynamicFlags::FLEXIBLE,
2400 )
2401 }
2402
2403 /// This enables verbose logging for the buffer collection.
2404 ///
2405 /// Verbose logging includes constraints set via
2406 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
2407 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
2408 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
2409 /// the tree of `Node`(s).
2410 ///
2411 /// Normally sysmem prints only a single line complaint when aggregation
2412 /// fails, with just the specific detailed reason that aggregation failed,
2413 /// with little surrounding context. While this is often enough to diagnose
2414 /// a problem if only a small change was made and everything was working
2415 /// before the small change, it's often not particularly helpful for getting
2416 /// a new buffer collection to work for the first time. Especially with
2417 /// more complex trees of nodes, involving things like
2418 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
2419 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
2420 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
2421 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
2422 /// looks like and why it's failing a logical allocation, or why a tree or
2423 /// subtree is failing sooner than expected.
2424 ///
2425 /// The intent of the extra logging is to be acceptable from a performance
2426 /// point of view, under the assumption that verbose logging is only enabled
2427 /// on a low number of buffer collections. If we're not tracking down a bug,
2428 /// we shouldn't send this message.
2429 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
2430 self.client.send::<fidl::encoding::EmptyPayload>(
2431 (),
2432 0x5209c77415b4dfad,
2433 fidl::encoding::DynamicFlags::FLEXIBLE,
2434 )
2435 }
2436
2437 /// This gets a handle that can be used as a parameter to
2438 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
2439 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
2440 /// client obtained this handle from this `Node`.
2441 ///
2442 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
2443 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
2444 /// despite the two calls typically being on different channels.
2445 ///
2446 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
2447 ///
2448 /// All table fields are currently required.
2449 ///
2450 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
2451 /// different `Node` channel, to prove that the client obtained the handle
2452 /// from this `Node`.
2453 pub fn r#get_node_ref(
2454 &self,
2455 ___deadline: zx::MonotonicInstant,
2456 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
2457 let _response = self.client.send_query::<
2458 fidl::encoding::EmptyPayload,
2459 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
2460 BufferCollectionMarker,
2461 >(
2462 (),
2463 0x5b3d0e51614df053,
2464 fidl::encoding::DynamicFlags::FLEXIBLE,
2465 ___deadline,
2466 )?
2467 .into_result::<BufferCollectionMarker>("get_node_ref")?;
2468 Ok(_response)
2469 }
2470
2471 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
2472 /// rooted at a different child token of a common parent
2473 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
2474 /// passed-in `node_ref`.
2475 ///
2476 /// This call is for assisting with admission control de-duplication, and
2477 /// with debugging.
2478 ///
2479 /// The `node_ref` must be obtained using
2480 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
2481 ///
2482 /// The `node_ref` can be a duplicated handle; it's not necessary to call
2483 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
2484 ///
2485 /// If a calling token may not actually be a valid token at all due to a
2486 /// potentially hostile/untrusted provider of the token, call
2487 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
2488 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
2489 /// never responds due to a calling token not being a real token (not really
2490 /// talking to sysmem). Another option is to call
2491 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
2492 /// which also validates the token along with converting it to a
2493 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
2494 ///
2495 /// All table fields are currently required.
2496 ///
2497 /// - response `is_alternate`
2498 /// - true: The first parent node in common between the calling node and
2499 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
2500 /// that the calling `Node` and the `node_ref` `Node` will not have both
2501 /// their constraints apply - rather sysmem will choose one or the other
2502 /// of the constraints - never both. This is because only one child of
2503 /// a `BufferCollectionTokenGroup` is selected during logical
2504 /// allocation, with only that one child's subtree contributing to
2505 /// constraints aggregation.
2506 /// - false: The first parent node in common between the calling `Node`
2507 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
2508 /// Currently, this means the first parent node in common is a
2509 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
2510 /// `Release`ed). This means that the calling `Node` and the `node_ref`
2511 /// `Node` may have both their constraints apply during constraints
2512 /// aggregation of the logical allocation, if both `Node`(s) are
2513 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
2514 /// this case, there is no `BufferCollectionTokenGroup` that will
2515 /// directly prevent the two `Node`(s) from both being selected and
2516 /// their constraints both aggregated, but even when false, one or both
2517 /// `Node`(s) may still be eliminated from consideration if one or both
2518 /// `Node`(s) has a direct or indirect parent
2519 /// `BufferCollectionTokenGroup` which selects a child subtree other
2520 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
2521 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
2522 /// associated with the same buffer collection as the calling `Node`.
2523 /// Another reason for this error is if the `node_ref` is an
2524 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
2525 /// a real `node_ref` obtained from `GetNodeRef`.
2526 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
2527 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
2528 /// the needed rights expected on a real `node_ref`.
2529 /// * No other failing status codes are returned by this call. However,
2530 /// sysmem may add additional codes in future, so the client should have
2531 /// sensible default handling for any failing status code.
2532 pub fn r#is_alternate_for(
2533 &self,
2534 mut payload: NodeIsAlternateForRequest,
2535 ___deadline: zx::MonotonicInstant,
2536 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
2537 let _response = self.client.send_query::<
2538 NodeIsAlternateForRequest,
2539 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
2540 BufferCollectionMarker,
2541 >(
2542 &mut payload,
2543 0x3a58e00157e0825,
2544 fidl::encoding::DynamicFlags::FLEXIBLE,
2545 ___deadline,
2546 )?
2547 .into_result::<BufferCollectionMarker>("is_alternate_for")?;
2548 Ok(_response.map(|x| x))
2549 }
2550
2551 /// Get the buffer collection ID. This ID is also available from
2552 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
2553 /// within the collection).
2554 ///
2555 /// This call is mainly useful in situations where we can't convey a
2556 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
2557 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
2558 /// handle, which can be joined back up with a `BufferCollection` client end
2559 /// that was created via a different path. Prefer to convey a
2560 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
2561 ///
2562 /// Trusting a `buffer_collection_id` value from a source other than sysmem
2563 /// is analogous to trusting a koid value from a source other than zircon.
2564 /// Both should be avoided unless really necessary, and both require
2565 /// caution. In some situations it may be reasonable to refer to a
2566 /// pre-established `BufferCollection` by `buffer_collection_id` via a
2567 /// protocol for efficiency reasons, but an incoming value purporting to be
2568 /// a `buffer_collection_id` is not sufficient alone to justify granting the
2569 /// sender of the `buffer_collection_id` any capability. The sender must
2570 /// first prove to a receiver that the sender has/had a VMO or has/had a
2571 /// `BufferCollectionToken` to the same collection by sending a handle that
2572 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
2573 /// `buffer_collection_id` value. The receiver should take care to avoid
2574 /// assuming that a sender had a `BufferCollectionToken` in cases where the
2575 /// sender has only proven that the sender had a VMO.
2576 ///
2577 /// - response `buffer_collection_id` This ID is unique per buffer
2578 /// collection per boot. Each buffer is uniquely identified by the
2579 /// `buffer_collection_id` and `buffer_index` together.
2580 pub fn r#get_buffer_collection_id(
2581 &self,
2582 ___deadline: zx::MonotonicInstant,
2583 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
2584 let _response = self.client.send_query::<
2585 fidl::encoding::EmptyPayload,
2586 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
2587 BufferCollectionMarker,
2588 >(
2589 (),
2590 0x77d19a494b78ba8c,
2591 fidl::encoding::DynamicFlags::FLEXIBLE,
2592 ___deadline,
2593 )?
2594 .into_result::<BufferCollectionMarker>("get_buffer_collection_id")?;
2595 Ok(_response)
2596 }
2597
2598 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
2599 /// created after this message to weak, which means that a client's `Node`
2600 /// client end (or a child created after this message) is not alone
2601 /// sufficient to keep allocated VMOs alive.
2602 ///
2603 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
2604 /// `close_weak_asap`.
2605 ///
2606 /// This message is only permitted before the `Node` becomes ready for
2607 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
2608 /// * `BufferCollectionToken`: any time
2609 /// * `BufferCollection`: before `SetConstraints`
2610 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
2611 ///
2612 /// Currently, no conversion from strong `Node` to weak `Node` after ready
2613 /// for allocation is provided, but a client can simulate that by creating
2614 /// an additional `Node` before allocation and setting that additional
2615 /// `Node` to weak, and then potentially at some point later sending
2616 /// `Release` and closing the client end of the client's strong `Node`, but
2617 /// keeping the client's weak `Node`.
2618 ///
2619 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
2620 /// collection failure (all `Node` client end(s) will see
2621 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
2622 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
2623 /// this situation until all `Node`(s) are ready for allocation. For initial
2624 /// allocation to succeed, at least one strong `Node` is required to exist
2625 /// at allocation time, but after that client receives VMO handles, that
2626 /// client can `BufferCollection.Release` and close the client end without
2627 /// causing this type of failure.
2628 ///
2629 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
2630 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
2631 /// separately as appropriate.
2632 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
2633 self.client.send::<fidl::encoding::EmptyPayload>(
2634 (),
2635 0x22dd3ea514eeffe1,
2636 fidl::encoding::DynamicFlags::FLEXIBLE,
2637 )
2638 }
2639
2640 /// This indicates to sysmem that the client is prepared to pay attention to
2641 /// `close_weak_asap`.
2642 ///
2643 /// If sent, this message must be before
2644 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
2645 ///
2646 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
2647 /// send this message before `WaitForAllBuffersAllocated`, or a parent
2648 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
2649 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
2650 /// trigger buffer collection failure.
2651 ///
2652 /// This message is necessary because weak sysmem VMOs have not always been
2653 /// a thing, so older clients are not aware of the need to pay attention to
2654 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
2655 /// sysmem weak VMO handles asap. By having this message and requiring
2656 /// participants to indicate their acceptance of this aspect of the overall
2657 /// protocol, we avoid situations where an older client is delivered a weak
2658 /// VMO without any way for sysmem to get that VMO to close quickly later
2659 /// (and on a per-buffer basis).
2660 ///
2661 /// A participant that doesn't handle `close_weak_asap` and also doesn't
2662 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
2663 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
2664 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
2665 /// same participant has a child/delegate which does retrieve VMOs, that
2666 /// child/delegate will need to send `SetWeakOk` before
2667 /// `WaitForAllBuffersAllocated`.
2668 ///
2669 /// + request `for_child_nodes_also` If present and true, this means direct
2670 /// child nodes of this node created after this message plus all
2671 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
2672 /// those nodes. Any child node of this node that was created before this
2673 /// message is not included. This setting is "sticky" in the sense that a
2674 /// subsequent `SetWeakOk` without this bool set to true does not reset
2675 /// the server-side bool. If this creates a problem for a participant, a
2676 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
2677 /// tokens instead, as appropriate. A participant should only set
2678 /// `for_child_nodes_also` true if the participant can really promise to
2679 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
2680 /// weak VMO handles held by participants holding the corresponding child
2681 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
2682 /// which are using sysmem(1) can be weak, despite the clients of those
2683 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
2684 /// direct way to find out about `close_weak_asap`. This only applies to
2685 /// descendents of this `Node` which are using sysmem(1), not to this
2686 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
2687 /// token, which will fail allocation unless an ancestor of this `Node`
2688 /// specified `for_child_nodes_also` true.
2689 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
2690 self.client.send::<NodeSetWeakOkRequest>(
2691 &mut payload,
2692 0x38a44fc4d7724be9,
2693 fidl::encoding::DynamicFlags::FLEXIBLE,
2694 )
2695 }
2696
2697 /// The server_end will be closed after this `Node` and any child nodes have
2698 /// have released their buffer counts, making those counts available for
2699 /// reservation by a different `Node` via
2700 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
2701 ///
2702 /// The `Node` buffer counts may not be released until the entire tree of
2703 /// `Node`(s) is closed or failed, because
2704 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
2705 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
2706 /// `Node` buffer counts remain reserved until the orphaned node is later
2707 /// cleaned up.
2708 ///
2709 /// If the `Node` exceeds a fairly large number of attached eventpair server
2710 /// ends, a log message will indicate this and the `Node` (and the
2711 /// appropriate) sub-tree will fail.
2712 ///
2713 /// The `server_end` will remain open when
2714 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
2715 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
2716 /// [`fuchsia.sysmem2/BufferCollection`].
2717 ///
2718 /// This message can also be used with a
2719 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
2720 pub fn r#attach_node_tracking(
2721 &self,
2722 mut payload: NodeAttachNodeTrackingRequest,
2723 ) -> Result<(), fidl::Error> {
2724 self.client.send::<NodeAttachNodeTrackingRequest>(
2725 &mut payload,
2726 0x3f22f2a293d3cdac,
2727 fidl::encoding::DynamicFlags::FLEXIBLE,
2728 )
2729 }
2730
2731 /// Provide [`fuchsia.sysmem2/BufferCollectionConstraints`] to the buffer
2732 /// collection.
2733 ///
2734 /// A participant may only call
2735 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] up to once per
2736 /// [`fuchsia.sysmem2/BufferCollection`].
2737 ///
2738 /// For buffer allocation to be attempted, all holders of a
2739 /// `BufferCollection` client end need to call `SetConstraints` before
2740 /// sysmem will attempt to allocate buffers.
2741 pub fn r#set_constraints(
2742 &self,
2743 mut payload: BufferCollectionSetConstraintsRequest,
2744 ) -> Result<(), fidl::Error> {
2745 self.client.send::<BufferCollectionSetConstraintsRequest>(
2746 &mut payload,
2747 0x1fde0f19d650197b,
2748 fidl::encoding::DynamicFlags::FLEXIBLE,
2749 )
2750 }
2751
2752 /// Wait until all buffers are allocated.
2753 ///
2754 /// This FIDL call completes when buffers have been allocated, or completes
2755 /// with some failure detail if allocation has been attempted but failed.
2756 ///
2757 /// The following must occur before buffers will be allocated:
2758 /// * All [`fuchsia.sysmem2/BufferCollectionToken`](s) of the buffer
2759 /// collection must be turned in via `BindSharedCollection` to get a
2760 /// [`fuchsia.sysmem2/BufferCollection`] (for brevity, this is assuming
2761 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`] isn't being used),
2762 /// or have had [`fuchsia.sysmem2/BufferCollectionToken.Release`] sent
2763 /// to them.
2764 /// * All [`fuchsia.sysmem2/BufferCollection`](s) of the buffer collection
2765 /// must have had [`fuchsia.sysmem2/BufferCollection.SetConstraints`]
2766 /// sent to them, or had [`fuchsia.sysmem2/BufferCollection.Release`]
2767 /// sent to them.
2768 ///
2769 /// - result `buffer_collection_info` The VMO handles and other related
2770 /// info.
2771 /// * error `[fuchsia.sysmem2/Error.NO_MEMORY]` The request is valid but
2772 /// cannot be fulfilled due to resource exhaustion.
2773 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION`] The request is
2774 /// malformed.
2775 /// * error `[fuchsia.sysmem2/Error.CONSTRAINTS_INTERSECTION_EMPTY`] The
2776 /// request is valid but cannot be satisfied, perhaps due to hardware
2777 /// limitations. This can happen if participants have incompatible
2778 /// constraints (empty intersection, roughly speaking). See the log for
2779 /// more info. In cases where a participant could potentially be treated
2780 /// as optional, see [`BufferCollectionTokenGroup`]. When using
2781 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], this will be the
2782 /// error code if there aren't enough buffers in the pre-existing
2783 /// collection to satisfy the constraints set on the attached token and
2784 /// any sub-tree of tokens derived from the attached token.
2785 pub fn r#wait_for_all_buffers_allocated(
2786 &self,
2787 ___deadline: zx::MonotonicInstant,
2788 ) -> Result<BufferCollectionWaitForAllBuffersAllocatedResult, fidl::Error> {
2789 let _response = self
2790 .client
2791 .send_query::<fidl::encoding::EmptyPayload, fidl::encoding::FlexibleResultType<
2792 BufferCollectionWaitForAllBuffersAllocatedResponse,
2793 Error,
2794 >, BufferCollectionMarker>(
2795 (),
2796 0x62300344b61404e,
2797 fidl::encoding::DynamicFlags::FLEXIBLE,
2798 ___deadline,
2799 )?
2800 .into_result::<BufferCollectionMarker>("wait_for_all_buffers_allocated")?;
2801 Ok(_response.map(|x| x))
2802 }
2803
2804 /// Checks whether all the buffers have been allocated, in a polling
2805 /// fashion.
2806 ///
2807 /// * If the buffer collection has been allocated, returns success.
2808 /// * If the buffer collection failed allocation, returns the same
2809 /// [`fuchsia.sysmem2/Error`] as
2810 /// [`fuchsia.sysmem2/BufferCollection/WaitForAllBuffersAllocated`] would
2811 /// return.
2812 /// * error [`fuchsia.sysmem2/Error.PENDING`] The buffer collection hasn't
2813 /// attempted allocation yet. This means that WaitForAllBuffersAllocated
2814 /// would not respond quickly.
2815 pub fn r#check_all_buffers_allocated(
2816 &self,
2817 ___deadline: zx::MonotonicInstant,
2818 ) -> Result<BufferCollectionCheckAllBuffersAllocatedResult, fidl::Error> {
2819 let _response = self.client.send_query::<
2820 fidl::encoding::EmptyPayload,
2821 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
2822 BufferCollectionMarker,
2823 >(
2824 (),
2825 0x35a5fe77ce939c10,
2826 fidl::encoding::DynamicFlags::FLEXIBLE,
2827 ___deadline,
2828 )?
2829 .into_result::<BufferCollectionMarker>("check_all_buffers_allocated")?;
2830 Ok(_response.map(|x| x))
2831 }
2832
2833 /// Create a new token to add a new participant to an existing logical
2834 /// buffer collection, if the existing collection's buffer counts,
2835 /// constraints, and participants allow.
2836 ///
2837 /// This can be useful in replacing a failed participant, and/or in
2838 /// adding/re-adding a participant after buffers have already been
2839 /// allocated.
2840 ///
2841 /// When [`fuchsia.sysmem2/BufferCollection.AttachToken`] is used, the sub
2842 /// tree rooted at the attached [`fuchsia.sysmem2/BufferCollectionToken`]
2843 /// goes through the normal procedure of setting constraints or closing
2844 /// [`fuchsia.sysmem2/Node`](s), and then appearing to allocate buffers from
2845 /// clients' point of view, despite the possibility that all the buffers
2846 /// were actually allocated previously. This process is called "logical
2847 /// allocation". Most instances of "allocation" in docs for other messages
2848 /// can also be read as "allocation or logical allocation" while remaining
2849 /// valid, but we just say "allocation" in most places for brevity/clarity
2850 /// of explanation, with the details of "logical allocation" left for the
2851 /// docs here on `AttachToken`.
2852 ///
2853 /// Failure of an attached `Node` does not propagate to the parent of the
2854 /// attached `Node`. More generally, failure of a child `Node` is blocked
2855 /// from reaching its parent `Node` if the child is attached, or if the
2856 /// child is dispensable and the failure occurred after logical allocation
2857 /// (see [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`]).
2858 ///
2859 /// A participant may in some scenarios choose to initially use a
2860 /// dispensable token for a given instance of a delegate participant, and
2861 /// then later if the first instance of that delegate participant fails, a
2862 /// new second instance of that delegate participant my be given a token
2863 /// created with `AttachToken`.
2864 ///
2865 /// From the point of view of the [`fuchsia.sysmem2/BufferCollectionToken`]
2866 /// client end, the token acts like any other token. The client can
2867 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] the token as needed,
2868 /// and can send the token to a different process/participant. The
2869 /// `BufferCollectionToken` `Node` should be converted to a
2870 /// `BufferCollection` `Node` as normal by sending
2871 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or can be closed
2872 /// without causing subtree failure by sending
2873 /// [`fuchsia.sysmem2/BufferCollectionToken.Release`]. Assuming the former,
2874 /// the [`fuchsia.sysmem2/BufferCollection.SetConstraints`] message or
2875 /// [`fuchsia.sysmem2/BufferCollection.Release`] message should be sent to
2876 /// the `BufferCollection`.
2877 ///
2878 /// Within the subtree, a success result from
2879 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`] means
2880 /// the subtree participants' constraints were satisfiable using the
2881 /// already-existing buffer collection, the already-established
2882 /// [`fuchsia.sysmem2/BufferCollectionInfo`] including image format
2883 /// constraints, and the already-existing other participants (already added
2884 /// via successful logical allocation) and their specified buffer counts in
2885 /// their constraints. A failure result means the new participants'
2886 /// constraints cannot be satisfied using the existing buffer collection and
2887 /// its already-added participants. Creating a new collection instead may
2888 /// allow all participants' constraints to be satisfied, assuming
2889 /// `SetDispensable` is used in place of `AttachToken`, or a normal token is
2890 /// used.
2891 ///
2892 /// A token created with `AttachToken` performs constraints aggregation with
2893 /// all constraints currently in effect on the buffer collection, plus the
2894 /// attached token under consideration plus child tokens under the attached
2895 /// token which are not themselves an attached token or under such a token.
2896 /// Further subtrees under this subtree are considered for logical
2897 /// allocation only after this subtree has completed logical allocation.
2898 ///
2899 /// Assignment of existing buffers to participants'
2900 /// [`fuchsia.sysmem2/BufferCollectionConstraints.min_buffer_count_for_camping`]
2901 /// etc is first-come first-served, but a child can't logically allocate
2902 /// before all its parents have sent `SetConstraints`.
2903 ///
2904 /// See also [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`], which
2905 /// in contrast to `AttachToken`, has the created token `Node` + child
2906 /// `Node`(s) (in the created subtree but not in any subtree under this
2907 /// subtree) participate in constraints aggregation along with its parent
2908 /// during the parent's allocation or logical allocation.
2909 ///
2910 /// Similar to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], the
2911 /// newly created token needs to be [`fuchsia.sysmem2/Node.Sync`]ed to
2912 /// sysmem before the new token can be passed to `BindSharedCollection`. The
2913 /// `Sync` of the new token can be accomplished with
2914 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after converting the created
2915 /// `BufferCollectionToken` to a `BufferCollection`. Alternately,
2916 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on the new token also
2917 /// works. Or using [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`]
2918 /// works. As usual, a `BufferCollectionToken.Sync` can be started after any
2919 /// `BufferCollectionToken.Duplicate` messages have been sent via the newly
2920 /// created token, to also sync those additional tokens to sysmem using a
2921 /// single round-trip.
2922 ///
2923 /// All table fields are currently required.
2924 ///
2925 /// + request `rights_attentuation_mask` This allows attenuating the VMO
2926 /// rights of the subtree. These values for `rights_attenuation_mask`
2927 /// result in no attenuation (note that 0 is not on this list):
2928 /// + ZX_RIGHT_SAME_RIGHTS (preferred)
2929 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
2930 /// + request `token_request` The server end of the `BufferCollectionToken`
2931 /// channel. The client retains the client end.
2932 pub fn r#attach_token(
2933 &self,
2934 mut payload: BufferCollectionAttachTokenRequest,
2935 ) -> Result<(), fidl::Error> {
2936 self.client.send::<BufferCollectionAttachTokenRequest>(
2937 &mut payload,
2938 0x46ac7d0008492982,
2939 fidl::encoding::DynamicFlags::FLEXIBLE,
2940 )
2941 }
2942
2943 /// Set up an eventpair to be signalled (`ZX_EVENTPAIR_PEER_CLOSED`) when
2944 /// buffers have been allocated and only the specified number of buffers (or
2945 /// fewer) remain in the buffer collection.
2946 ///
2947 /// [`fuchsia.sysmem2/BufferCollection.AttachLifetimeTracking`] allows a
2948 /// client to wait until an old buffer collection is fully or mostly
2949 /// deallocated before attempting allocation of a new buffer collection. The
2950 /// eventpair is only signalled when the buffers of this collection have
2951 /// been fully deallocated (not just un-referenced by clients, but all the
2952 /// memory consumed by those buffers has been fully reclaimed/recycled), or
2953 /// when allocation or logical allocation fails for the tree or subtree
2954 /// including this [`fuchsia.sysmem2/BufferCollection`].
2955 ///
2956 /// The eventpair won't be signalled until allocation or logical allocation
2957 /// has completed; until then, the collection's current buffer count is
2958 /// ignored.
2959 ///
2960 /// If logical allocation fails for an attached subtree (using
2961 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]), the server end of the
2962 /// eventpair will close during that failure regardless of the number of
2963 /// buffers potenitally allocated in the overall buffer collection. This is
2964 /// for logical allocation consistency with normal allocation.
2965 ///
2966 /// The lifetime signalled by this event includes asynchronous cleanup of
2967 /// allocated buffers, and this asynchronous cleanup cannot occur until all
2968 /// holders of VMO handles to the buffers have closed those VMO handles.
2969 /// Therefore, clients should take care not to become blocked forever
2970 /// waiting for `ZX_EVENTPAIR_PEER_CLOSED` to be signalled if any of the
2971 /// participants using the logical buffer collection (including the waiter
2972 /// itself) are less trusted, less reliable, or potentially blocked by the
2973 /// wait itself. Waiting asynchronously is recommended. Setting a deadline
2974 /// for the client wait may be prudent, depending on details of how the
2975 /// collection and/or its VMOs are used or shared. Failure to allocate a
2976 /// new/replacement buffer collection is better than getting stuck forever.
2977 ///
2978 /// The sysmem server itself intentionally does not perform any waiting on
2979 /// already-failed collections' VMOs to finish cleaning up before attempting
2980 /// a new allocation, and the sysmem server intentionally doesn't retry
2981 /// allocation if a new allocation fails due to out of memory, even if that
2982 /// failure is potentially due to continued existence of an old collection's
2983 /// VMOs. This `AttachLifetimeTracking` message is how an initiator can
2984 /// mitigate too much overlap of old VMO lifetimes with new VMO lifetimes,
2985 /// as long as the waiting client is careful to not create a deadlock.
2986 ///
2987 /// Continued existence of old collections that are still cleaning up is not
2988 /// the only reason that a new allocation may fail due to insufficient
2989 /// memory, even if the new allocation is allocating physically contiguous
2990 /// buffers. Overall system memory pressure can also be the cause of failure
2991 /// to allocate a new collection. See also
2992 /// [`fuchsia.memorypressure/Provider`].
2993 ///
2994 /// `AttachLifetimeTracking` is meant to be compatible with other protocols
2995 /// with a similar `AttachLifetimeTracking` message; duplicates of the same
2996 /// `eventpair` handle (server end) can be sent via more than one
2997 /// `AttachLifetimeTracking` message to different protocols, and the
2998 /// `ZX_EVENTPAIR_PEER_CLOSED` will be signalled for the client end when all
2999 /// the conditions are met (all holders of duplicates have closed their
3000 /// server end handle(s)). Also, thanks to how eventpair endponts work, the
3001 /// client end can (also) be duplicated without preventing the
3002 /// `ZX_EVENTPAIR_PEER_CLOSED` signal.
3003 ///
3004 /// The server intentionally doesn't "trust" any signals set on the
3005 /// `server_end`. This mechanism intentionally uses only
3006 /// `ZX_EVENTPAIR_PEER_CLOSED` set on the client end, which can't be set
3007 /// "early", and is only set when all handles to the server end eventpair
3008 /// are closed. No meaning is associated with any of the other signals, and
3009 /// clients should ignore any other signal bits on either end of the
3010 /// `eventpair`.
3011 ///
3012 /// The `server_end` may lack `ZX_RIGHT_SIGNAL` or `ZX_RIGHT_SIGNAL_PEER`,
3013 /// but must have `ZX_RIGHT_DUPLICATE` (and must have `ZX_RIGHT_TRANSFER` to
3014 /// transfer without causing `BufferCollection` channel failure).
3015 ///
3016 /// All table fields are currently required.
3017 ///
3018 /// + request `server_end` This eventpair handle will be closed by the
3019 /// sysmem server when buffers have been allocated initially and the
3020 /// number of buffers is then less than or equal to `buffers_remaining`.
3021 /// + request `buffers_remaining` Wait for all but `buffers_remaining` (or
3022 /// fewer) buffers to be fully deallocated. A number greater than zero can
3023 /// be useful in situations where a known number of buffers are
3024 /// intentionally not closed so that the data can continue to be used,
3025 /// such as for keeping the last available video frame displayed in the UI
3026 /// even if the video stream was using protected output buffers. It's
3027 /// outside the scope of the `BufferCollection` interface (at least for
3028 /// now) to determine how many buffers may be held without closing, but
3029 /// it'll typically be in the range 0-2.
3030 pub fn r#attach_lifetime_tracking(
3031 &self,
3032 mut payload: BufferCollectionAttachLifetimeTrackingRequest,
3033 ) -> Result<(), fidl::Error> {
3034 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
3035 &mut payload,
3036 0x3ecb510113116dcf,
3037 fidl::encoding::DynamicFlags::FLEXIBLE,
3038 )
3039 }
3040}
3041
3042#[cfg(target_os = "fuchsia")]
3043impl From<BufferCollectionSynchronousProxy> for zx::NullableHandle {
3044 fn from(value: BufferCollectionSynchronousProxy) -> Self {
3045 value.into_channel().into()
3046 }
3047}
3048
3049#[cfg(target_os = "fuchsia")]
3050impl From<fidl::Channel> for BufferCollectionSynchronousProxy {
3051 fn from(value: fidl::Channel) -> Self {
3052 Self::new(value)
3053 }
3054}
3055
3056#[cfg(target_os = "fuchsia")]
3057impl fidl::endpoints::FromClient for BufferCollectionSynchronousProxy {
3058 type Protocol = BufferCollectionMarker;
3059
3060 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionMarker>) -> Self {
3061 Self::new(value.into_channel())
3062 }
3063}
3064
3065#[derive(Debug, Clone)]
3066pub struct BufferCollectionProxy {
3067 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
3068}
3069
3070impl fidl::endpoints::Proxy for BufferCollectionProxy {
3071 type Protocol = BufferCollectionMarker;
3072
3073 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
3074 Self::new(inner)
3075 }
3076
3077 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
3078 self.client.into_channel().map_err(|client| Self { client })
3079 }
3080
3081 fn as_channel(&self) -> &::fidl::AsyncChannel {
3082 self.client.as_channel()
3083 }
3084}
3085
3086impl BufferCollectionProxy {
3087 /// Create a new Proxy for fuchsia.sysmem2/BufferCollection.
3088 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
3089 let protocol_name = <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
3090 Self { client: fidl::client::Client::new(channel, protocol_name) }
3091 }
3092
3093 /// Get a Stream of events from the remote end of the protocol.
3094 ///
3095 /// # Panics
3096 ///
3097 /// Panics if the event stream was already taken.
3098 pub fn take_event_stream(&self) -> BufferCollectionEventStream {
3099 BufferCollectionEventStream { event_receiver: self.client.take_event_receiver() }
3100 }
3101
3102 /// Ensure that previous messages have been received server side. This is
3103 /// particularly useful after previous messages that created new tokens,
3104 /// because a token must be known to the sysmem server before sending the
3105 /// token to another participant.
3106 ///
3107 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
3108 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
3109 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
3110 /// to mitigate the possibility of a hostile/fake
3111 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
3112 /// Another way is to pass the token to
3113 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
3114 /// the token as part of exchanging it for a
3115 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
3116 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
3117 /// of stalling.
3118 ///
3119 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
3120 /// and then starting and completing a `Sync`, it's then safe to send the
3121 /// `BufferCollectionToken` client ends to other participants knowing the
3122 /// server will recognize the tokens when they're sent by the other
3123 /// participants to sysmem in a
3124 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
3125 /// efficient way to create tokens while avoiding unnecessary round trips.
3126 ///
3127 /// Other options include waiting for each
3128 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
3129 /// individually (using separate call to `Sync` after each), or calling
3130 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
3131 /// converted to a `BufferCollection` via
3132 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
3133 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
3134 /// the sync step and can create multiple tokens at once.
3135 pub fn r#sync(
3136 &self,
3137 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
3138 BufferCollectionProxyInterface::r#sync(self)
3139 }
3140
3141 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
3142 ///
3143 /// Normally a participant will convert a `BufferCollectionToken` into a
3144 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
3145 /// `Release` via the token (and then close the channel immediately or
3146 /// shortly later in response to server closing the server end), which
3147 /// avoids causing buffer collection failure. Without a prior `Release`,
3148 /// closing the `BufferCollectionToken` client end will cause buffer
3149 /// collection failure.
3150 ///
3151 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
3152 ///
3153 /// By default the server handles unexpected closure of a
3154 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
3155 /// first) by failing the buffer collection. Partly this is to expedite
3156 /// closing VMO handles to reclaim memory when any participant fails. If a
3157 /// participant would like to cleanly close a `BufferCollection` without
3158 /// causing buffer collection failure, the participant can send `Release`
3159 /// before closing the `BufferCollection` client end. The `Release` can
3160 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
3161 /// buffer collection won't require constraints from this node in order to
3162 /// allocate. If after `SetConstraints`, the constraints are retained and
3163 /// aggregated, despite the lack of `BufferCollection` connection at the
3164 /// time of constraints aggregation.
3165 ///
3166 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
3167 ///
3168 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
3169 /// end (without `Release` first) will trigger failure of the buffer
3170 /// collection. To close a `BufferCollectionTokenGroup` channel without
3171 /// failing the buffer collection, ensure that AllChildrenPresent() has been
3172 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
3173 /// client end.
3174 ///
3175 /// If `Release` occurs before
3176 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
3177 /// buffer collection will fail (triggered by reception of `Release` without
3178 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
3179 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
3180 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
3181 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
3182 /// close requires `AllChildrenPresent` (if not already sent), then
3183 /// `Release`, then close client end.
3184 ///
3185 /// If `Release` occurs after `AllChildrenPresent`, the children and all
3186 /// their constraints remain intact (just as they would if the
3187 /// `BufferCollectionTokenGroup` channel had remained open), and the client
3188 /// end close doesn't trigger buffer collection failure.
3189 ///
3190 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
3191 ///
3192 /// For brevity, the per-channel-protocol paragraphs above ignore the
3193 /// separate failure domain created by
3194 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
3195 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
3196 /// unexpectedly closes (without `Release` first) and that client end is
3197 /// under a failure domain, instead of failing the whole buffer collection,
3198 /// the failure domain is failed, but the buffer collection itself is
3199 /// isolated from failure of the failure domain. Such failure domains can be
3200 /// nested, in which case only the inner-most failure domain in which the
3201 /// `Node` resides fails.
3202 pub fn r#release(&self) -> Result<(), fidl::Error> {
3203 BufferCollectionProxyInterface::r#release(self)
3204 }
3205
3206 /// Set a name for VMOs in this buffer collection.
3207 ///
3208 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
3209 /// will be truncated to fit. The name of the vmo will be suffixed with the
3210 /// buffer index within the collection (if the suffix fits within
3211 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
3212 /// listed in the inspect data.
3213 ///
3214 /// The name only affects VMOs allocated after the name is set; this call
3215 /// does not rename existing VMOs. If multiple clients set different names
3216 /// then the larger priority value will win. Setting a new name with the
3217 /// same priority as a prior name doesn't change the name.
3218 ///
3219 /// All table fields are currently required.
3220 ///
3221 /// + request `priority` The name is only set if this is the first `SetName`
3222 /// or if `priority` is greater than any previous `priority` value in
3223 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
3224 /// + request `name` The name for VMOs created under this buffer collection.
3225 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
3226 BufferCollectionProxyInterface::r#set_name(self, payload)
3227 }
3228
3229 /// Set information about the current client that can be used by sysmem to
3230 /// help diagnose leaking memory and allocation stalls waiting for a
3231 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
3232 ///
3233 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
3234 /// `Node`(s) derived from this `Node`, unless overriden by
3235 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
3236 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
3237 ///
3238 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
3239 /// `Allocator` is the most efficient way to ensure that all
3240 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
3241 /// set, and is also more efficient than separately sending the same debug
3242 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
3243 /// created [`fuchsia.sysmem2/Node`].
3244 ///
3245 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
3246 /// indicate which client is closing their channel first, leading to subtree
3247 /// failure (which can be normal if the purpose of the subtree is over, but
3248 /// if happening earlier than expected, the client-channel-specific name can
3249 /// help diagnose where the failure is first coming from, from sysmem's
3250 /// point of view).
3251 ///
3252 /// All table fields are currently required.
3253 ///
3254 /// + request `name` This can be an arbitrary string, but the current
3255 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
3256 /// + request `id` This can be an arbitrary id, but the current process ID
3257 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
3258 pub fn r#set_debug_client_info(
3259 &self,
3260 mut payload: &NodeSetDebugClientInfoRequest,
3261 ) -> Result<(), fidl::Error> {
3262 BufferCollectionProxyInterface::r#set_debug_client_info(self, payload)
3263 }
3264
3265 /// Sysmem logs a warning if sysmem hasn't seen
3266 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
3267 /// within 5 seconds after creation of a new collection.
3268 ///
3269 /// Clients can call this method to change when the log is printed. If
3270 /// multiple client set the deadline, it's unspecified which deadline will
3271 /// take effect.
3272 ///
3273 /// In most cases the default works well.
3274 ///
3275 /// All table fields are currently required.
3276 ///
3277 /// + request `deadline` The time at which sysmem will start trying to log
3278 /// the warning, unless all constraints are with sysmem by then.
3279 pub fn r#set_debug_timeout_log_deadline(
3280 &self,
3281 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
3282 ) -> Result<(), fidl::Error> {
3283 BufferCollectionProxyInterface::r#set_debug_timeout_log_deadline(self, payload)
3284 }
3285
3286 /// This enables verbose logging for the buffer collection.
3287 ///
3288 /// Verbose logging includes constraints set via
3289 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
3290 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
3291 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
3292 /// the tree of `Node`(s).
3293 ///
3294 /// Normally sysmem prints only a single line complaint when aggregation
3295 /// fails, with just the specific detailed reason that aggregation failed,
3296 /// with little surrounding context. While this is often enough to diagnose
3297 /// a problem if only a small change was made and everything was working
3298 /// before the small change, it's often not particularly helpful for getting
3299 /// a new buffer collection to work for the first time. Especially with
3300 /// more complex trees of nodes, involving things like
3301 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
3302 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
3303 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
3304 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
3305 /// looks like and why it's failing a logical allocation, or why a tree or
3306 /// subtree is failing sooner than expected.
3307 ///
3308 /// The intent of the extra logging is to be acceptable from a performance
3309 /// point of view, under the assumption that verbose logging is only enabled
3310 /// on a low number of buffer collections. If we're not tracking down a bug,
3311 /// we shouldn't send this message.
3312 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
3313 BufferCollectionProxyInterface::r#set_verbose_logging(self)
3314 }
3315
3316 /// This gets a handle that can be used as a parameter to
3317 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
3318 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
3319 /// client obtained this handle from this `Node`.
3320 ///
3321 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
3322 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
3323 /// despite the two calls typically being on different channels.
3324 ///
3325 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
3326 ///
3327 /// All table fields are currently required.
3328 ///
3329 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
3330 /// different `Node` channel, to prove that the client obtained the handle
3331 /// from this `Node`.
3332 pub fn r#get_node_ref(
3333 &self,
3334 ) -> fidl::client::QueryResponseFut<
3335 NodeGetNodeRefResponse,
3336 fidl::encoding::DefaultFuchsiaResourceDialect,
3337 > {
3338 BufferCollectionProxyInterface::r#get_node_ref(self)
3339 }
3340
3341 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
3342 /// rooted at a different child token of a common parent
3343 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
3344 /// passed-in `node_ref`.
3345 ///
3346 /// This call is for assisting with admission control de-duplication, and
3347 /// with debugging.
3348 ///
3349 /// The `node_ref` must be obtained using
3350 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
3351 ///
3352 /// The `node_ref` can be a duplicated handle; it's not necessary to call
3353 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
3354 ///
3355 /// If a calling token may not actually be a valid token at all due to a
3356 /// potentially hostile/untrusted provider of the token, call
3357 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
3358 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
3359 /// never responds due to a calling token not being a real token (not really
3360 /// talking to sysmem). Another option is to call
3361 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
3362 /// which also validates the token along with converting it to a
3363 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
3364 ///
3365 /// All table fields are currently required.
3366 ///
3367 /// - response `is_alternate`
3368 /// - true: The first parent node in common between the calling node and
3369 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
3370 /// that the calling `Node` and the `node_ref` `Node` will not have both
3371 /// their constraints apply - rather sysmem will choose one or the other
3372 /// of the constraints - never both. This is because only one child of
3373 /// a `BufferCollectionTokenGroup` is selected during logical
3374 /// allocation, with only that one child's subtree contributing to
3375 /// constraints aggregation.
3376 /// - false: The first parent node in common between the calling `Node`
3377 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
3378 /// Currently, this means the first parent node in common is a
3379 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
3380 /// `Release`ed). This means that the calling `Node` and the `node_ref`
3381 /// `Node` may have both their constraints apply during constraints
3382 /// aggregation of the logical allocation, if both `Node`(s) are
3383 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
3384 /// this case, there is no `BufferCollectionTokenGroup` that will
3385 /// directly prevent the two `Node`(s) from both being selected and
3386 /// their constraints both aggregated, but even when false, one or both
3387 /// `Node`(s) may still be eliminated from consideration if one or both
3388 /// `Node`(s) has a direct or indirect parent
3389 /// `BufferCollectionTokenGroup` which selects a child subtree other
3390 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
3391 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
3392 /// associated with the same buffer collection as the calling `Node`.
3393 /// Another reason for this error is if the `node_ref` is an
3394 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
3395 /// a real `node_ref` obtained from `GetNodeRef`.
3396 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
3397 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
3398 /// the needed rights expected on a real `node_ref`.
3399 /// * No other failing status codes are returned by this call. However,
3400 /// sysmem may add additional codes in future, so the client should have
3401 /// sensible default handling for any failing status code.
3402 pub fn r#is_alternate_for(
3403 &self,
3404 mut payload: NodeIsAlternateForRequest,
3405 ) -> fidl::client::QueryResponseFut<
3406 NodeIsAlternateForResult,
3407 fidl::encoding::DefaultFuchsiaResourceDialect,
3408 > {
3409 BufferCollectionProxyInterface::r#is_alternate_for(self, payload)
3410 }
3411
3412 /// Get the buffer collection ID. This ID is also available from
3413 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
3414 /// within the collection).
3415 ///
3416 /// This call is mainly useful in situations where we can't convey a
3417 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
3418 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
3419 /// handle, which can be joined back up with a `BufferCollection` client end
3420 /// that was created via a different path. Prefer to convey a
3421 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
3422 ///
3423 /// Trusting a `buffer_collection_id` value from a source other than sysmem
3424 /// is analogous to trusting a koid value from a source other than zircon.
3425 /// Both should be avoided unless really necessary, and both require
3426 /// caution. In some situations it may be reasonable to refer to a
3427 /// pre-established `BufferCollection` by `buffer_collection_id` via a
3428 /// protocol for efficiency reasons, but an incoming value purporting to be
3429 /// a `buffer_collection_id` is not sufficient alone to justify granting the
3430 /// sender of the `buffer_collection_id` any capability. The sender must
3431 /// first prove to a receiver that the sender has/had a VMO or has/had a
3432 /// `BufferCollectionToken` to the same collection by sending a handle that
3433 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
3434 /// `buffer_collection_id` value. The receiver should take care to avoid
3435 /// assuming that a sender had a `BufferCollectionToken` in cases where the
3436 /// sender has only proven that the sender had a VMO.
3437 ///
3438 /// - response `buffer_collection_id` This ID is unique per buffer
3439 /// collection per boot. Each buffer is uniquely identified by the
3440 /// `buffer_collection_id` and `buffer_index` together.
3441 pub fn r#get_buffer_collection_id(
3442 &self,
3443 ) -> fidl::client::QueryResponseFut<
3444 NodeGetBufferCollectionIdResponse,
3445 fidl::encoding::DefaultFuchsiaResourceDialect,
3446 > {
3447 BufferCollectionProxyInterface::r#get_buffer_collection_id(self)
3448 }
3449
3450 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
3451 /// created after this message to weak, which means that a client's `Node`
3452 /// client end (or a child created after this message) is not alone
3453 /// sufficient to keep allocated VMOs alive.
3454 ///
3455 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
3456 /// `close_weak_asap`.
3457 ///
3458 /// This message is only permitted before the `Node` becomes ready for
3459 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
3460 /// * `BufferCollectionToken`: any time
3461 /// * `BufferCollection`: before `SetConstraints`
3462 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
3463 ///
3464 /// Currently, no conversion from strong `Node` to weak `Node` after ready
3465 /// for allocation is provided, but a client can simulate that by creating
3466 /// an additional `Node` before allocation and setting that additional
3467 /// `Node` to weak, and then potentially at some point later sending
3468 /// `Release` and closing the client end of the client's strong `Node`, but
3469 /// keeping the client's weak `Node`.
3470 ///
3471 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
3472 /// collection failure (all `Node` client end(s) will see
3473 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
3474 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
3475 /// this situation until all `Node`(s) are ready for allocation. For initial
3476 /// allocation to succeed, at least one strong `Node` is required to exist
3477 /// at allocation time, but after that client receives VMO handles, that
3478 /// client can `BufferCollection.Release` and close the client end without
3479 /// causing this type of failure.
3480 ///
3481 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
3482 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
3483 /// separately as appropriate.
3484 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
3485 BufferCollectionProxyInterface::r#set_weak(self)
3486 }
3487
3488 /// This indicates to sysmem that the client is prepared to pay attention to
3489 /// `close_weak_asap`.
3490 ///
3491 /// If sent, this message must be before
3492 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
3493 ///
3494 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
3495 /// send this message before `WaitForAllBuffersAllocated`, or a parent
3496 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
3497 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
3498 /// trigger buffer collection failure.
3499 ///
3500 /// This message is necessary because weak sysmem VMOs have not always been
3501 /// a thing, so older clients are not aware of the need to pay attention to
3502 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
3503 /// sysmem weak VMO handles asap. By having this message and requiring
3504 /// participants to indicate their acceptance of this aspect of the overall
3505 /// protocol, we avoid situations where an older client is delivered a weak
3506 /// VMO without any way for sysmem to get that VMO to close quickly later
3507 /// (and on a per-buffer basis).
3508 ///
3509 /// A participant that doesn't handle `close_weak_asap` and also doesn't
3510 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
3511 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
3512 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
3513 /// same participant has a child/delegate which does retrieve VMOs, that
3514 /// child/delegate will need to send `SetWeakOk` before
3515 /// `WaitForAllBuffersAllocated`.
3516 ///
3517 /// + request `for_child_nodes_also` If present and true, this means direct
3518 /// child nodes of this node created after this message plus all
3519 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
3520 /// those nodes. Any child node of this node that was created before this
3521 /// message is not included. This setting is "sticky" in the sense that a
3522 /// subsequent `SetWeakOk` without this bool set to true does not reset
3523 /// the server-side bool. If this creates a problem for a participant, a
3524 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
3525 /// tokens instead, as appropriate. A participant should only set
3526 /// `for_child_nodes_also` true if the participant can really promise to
3527 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
3528 /// weak VMO handles held by participants holding the corresponding child
3529 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
3530 /// which are using sysmem(1) can be weak, despite the clients of those
3531 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
3532 /// direct way to find out about `close_weak_asap`. This only applies to
3533 /// descendents of this `Node` which are using sysmem(1), not to this
3534 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
3535 /// token, which will fail allocation unless an ancestor of this `Node`
3536 /// specified `for_child_nodes_also` true.
3537 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
3538 BufferCollectionProxyInterface::r#set_weak_ok(self, payload)
3539 }
3540
3541 /// The server_end will be closed after this `Node` and any child nodes have
3542 /// have released their buffer counts, making those counts available for
3543 /// reservation by a different `Node` via
3544 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
3545 ///
3546 /// The `Node` buffer counts may not be released until the entire tree of
3547 /// `Node`(s) is closed or failed, because
3548 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
3549 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
3550 /// `Node` buffer counts remain reserved until the orphaned node is later
3551 /// cleaned up.
3552 ///
3553 /// If the `Node` exceeds a fairly large number of attached eventpair server
3554 /// ends, a log message will indicate this and the `Node` (and the
3555 /// appropriate) sub-tree will fail.
3556 ///
3557 /// The `server_end` will remain open when
3558 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
3559 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
3560 /// [`fuchsia.sysmem2/BufferCollection`].
3561 ///
3562 /// This message can also be used with a
3563 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
3564 pub fn r#attach_node_tracking(
3565 &self,
3566 mut payload: NodeAttachNodeTrackingRequest,
3567 ) -> Result<(), fidl::Error> {
3568 BufferCollectionProxyInterface::r#attach_node_tracking(self, payload)
3569 }
3570
3571 /// Provide [`fuchsia.sysmem2/BufferCollectionConstraints`] to the buffer
3572 /// collection.
3573 ///
3574 /// A participant may only call
3575 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] up to once per
3576 /// [`fuchsia.sysmem2/BufferCollection`].
3577 ///
3578 /// For buffer allocation to be attempted, all holders of a
3579 /// `BufferCollection` client end need to call `SetConstraints` before
3580 /// sysmem will attempt to allocate buffers.
3581 pub fn r#set_constraints(
3582 &self,
3583 mut payload: BufferCollectionSetConstraintsRequest,
3584 ) -> Result<(), fidl::Error> {
3585 BufferCollectionProxyInterface::r#set_constraints(self, payload)
3586 }
3587
3588 /// Wait until all buffers are allocated.
3589 ///
3590 /// This FIDL call completes when buffers have been allocated, or completes
3591 /// with some failure detail if allocation has been attempted but failed.
3592 ///
3593 /// The following must occur before buffers will be allocated:
3594 /// * All [`fuchsia.sysmem2/BufferCollectionToken`](s) of the buffer
3595 /// collection must be turned in via `BindSharedCollection` to get a
3596 /// [`fuchsia.sysmem2/BufferCollection`] (for brevity, this is assuming
3597 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`] isn't being used),
3598 /// or have had [`fuchsia.sysmem2/BufferCollectionToken.Release`] sent
3599 /// to them.
3600 /// * All [`fuchsia.sysmem2/BufferCollection`](s) of the buffer collection
3601 /// must have had [`fuchsia.sysmem2/BufferCollection.SetConstraints`]
3602 /// sent to them, or had [`fuchsia.sysmem2/BufferCollection.Release`]
3603 /// sent to them.
3604 ///
3605 /// - result `buffer_collection_info` The VMO handles and other related
3606 /// info.
3607 /// * error `[fuchsia.sysmem2/Error.NO_MEMORY]` The request is valid but
3608 /// cannot be fulfilled due to resource exhaustion.
3609 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION`] The request is
3610 /// malformed.
3611 /// * error `[fuchsia.sysmem2/Error.CONSTRAINTS_INTERSECTION_EMPTY`] The
3612 /// request is valid but cannot be satisfied, perhaps due to hardware
3613 /// limitations. This can happen if participants have incompatible
3614 /// constraints (empty intersection, roughly speaking). See the log for
3615 /// more info. In cases where a participant could potentially be treated
3616 /// as optional, see [`BufferCollectionTokenGroup`]. When using
3617 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], this will be the
3618 /// error code if there aren't enough buffers in the pre-existing
3619 /// collection to satisfy the constraints set on the attached token and
3620 /// any sub-tree of tokens derived from the attached token.
3621 pub fn r#wait_for_all_buffers_allocated(
3622 &self,
3623 ) -> fidl::client::QueryResponseFut<
3624 BufferCollectionWaitForAllBuffersAllocatedResult,
3625 fidl::encoding::DefaultFuchsiaResourceDialect,
3626 > {
3627 BufferCollectionProxyInterface::r#wait_for_all_buffers_allocated(self)
3628 }
3629
3630 /// Checks whether all the buffers have been allocated, in a polling
3631 /// fashion.
3632 ///
3633 /// * If the buffer collection has been allocated, returns success.
3634 /// * If the buffer collection failed allocation, returns the same
3635 /// [`fuchsia.sysmem2/Error`] as
3636 /// [`fuchsia.sysmem2/BufferCollection/WaitForAllBuffersAllocated`] would
3637 /// return.
3638 /// * error [`fuchsia.sysmem2/Error.PENDING`] The buffer collection hasn't
3639 /// attempted allocation yet. This means that WaitForAllBuffersAllocated
3640 /// would not respond quickly.
3641 pub fn r#check_all_buffers_allocated(
3642 &self,
3643 ) -> fidl::client::QueryResponseFut<
3644 BufferCollectionCheckAllBuffersAllocatedResult,
3645 fidl::encoding::DefaultFuchsiaResourceDialect,
3646 > {
3647 BufferCollectionProxyInterface::r#check_all_buffers_allocated(self)
3648 }
3649
3650 /// Create a new token to add a new participant to an existing logical
3651 /// buffer collection, if the existing collection's buffer counts,
3652 /// constraints, and participants allow.
3653 ///
3654 /// This can be useful in replacing a failed participant, and/or in
3655 /// adding/re-adding a participant after buffers have already been
3656 /// allocated.
3657 ///
3658 /// When [`fuchsia.sysmem2/BufferCollection.AttachToken`] is used, the sub
3659 /// tree rooted at the attached [`fuchsia.sysmem2/BufferCollectionToken`]
3660 /// goes through the normal procedure of setting constraints or closing
3661 /// [`fuchsia.sysmem2/Node`](s), and then appearing to allocate buffers from
3662 /// clients' point of view, despite the possibility that all the buffers
3663 /// were actually allocated previously. This process is called "logical
3664 /// allocation". Most instances of "allocation" in docs for other messages
3665 /// can also be read as "allocation or logical allocation" while remaining
3666 /// valid, but we just say "allocation" in most places for brevity/clarity
3667 /// of explanation, with the details of "logical allocation" left for the
3668 /// docs here on `AttachToken`.
3669 ///
3670 /// Failure of an attached `Node` does not propagate to the parent of the
3671 /// attached `Node`. More generally, failure of a child `Node` is blocked
3672 /// from reaching its parent `Node` if the child is attached, or if the
3673 /// child is dispensable and the failure occurred after logical allocation
3674 /// (see [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`]).
3675 ///
3676 /// A participant may in some scenarios choose to initially use a
3677 /// dispensable token for a given instance of a delegate participant, and
3678 /// then later if the first instance of that delegate participant fails, a
3679 /// new second instance of that delegate participant my be given a token
3680 /// created with `AttachToken`.
3681 ///
3682 /// From the point of view of the [`fuchsia.sysmem2/BufferCollectionToken`]
3683 /// client end, the token acts like any other token. The client can
3684 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] the token as needed,
3685 /// and can send the token to a different process/participant. The
3686 /// `BufferCollectionToken` `Node` should be converted to a
3687 /// `BufferCollection` `Node` as normal by sending
3688 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or can be closed
3689 /// without causing subtree failure by sending
3690 /// [`fuchsia.sysmem2/BufferCollectionToken.Release`]. Assuming the former,
3691 /// the [`fuchsia.sysmem2/BufferCollection.SetConstraints`] message or
3692 /// [`fuchsia.sysmem2/BufferCollection.Release`] message should be sent to
3693 /// the `BufferCollection`.
3694 ///
3695 /// Within the subtree, a success result from
3696 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`] means
3697 /// the subtree participants' constraints were satisfiable using the
3698 /// already-existing buffer collection, the already-established
3699 /// [`fuchsia.sysmem2/BufferCollectionInfo`] including image format
3700 /// constraints, and the already-existing other participants (already added
3701 /// via successful logical allocation) and their specified buffer counts in
3702 /// their constraints. A failure result means the new participants'
3703 /// constraints cannot be satisfied using the existing buffer collection and
3704 /// its already-added participants. Creating a new collection instead may
3705 /// allow all participants' constraints to be satisfied, assuming
3706 /// `SetDispensable` is used in place of `AttachToken`, or a normal token is
3707 /// used.
3708 ///
3709 /// A token created with `AttachToken` performs constraints aggregation with
3710 /// all constraints currently in effect on the buffer collection, plus the
3711 /// attached token under consideration plus child tokens under the attached
3712 /// token which are not themselves an attached token or under such a token.
3713 /// Further subtrees under this subtree are considered for logical
3714 /// allocation only after this subtree has completed logical allocation.
3715 ///
3716 /// Assignment of existing buffers to participants'
3717 /// [`fuchsia.sysmem2/BufferCollectionConstraints.min_buffer_count_for_camping`]
3718 /// etc is first-come first-served, but a child can't logically allocate
3719 /// before all its parents have sent `SetConstraints`.
3720 ///
3721 /// See also [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`], which
3722 /// in contrast to `AttachToken`, has the created token `Node` + child
3723 /// `Node`(s) (in the created subtree but not in any subtree under this
3724 /// subtree) participate in constraints aggregation along with its parent
3725 /// during the parent's allocation or logical allocation.
3726 ///
3727 /// Similar to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], the
3728 /// newly created token needs to be [`fuchsia.sysmem2/Node.Sync`]ed to
3729 /// sysmem before the new token can be passed to `BindSharedCollection`. The
3730 /// `Sync` of the new token can be accomplished with
3731 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after converting the created
3732 /// `BufferCollectionToken` to a `BufferCollection`. Alternately,
3733 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on the new token also
3734 /// works. Or using [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`]
3735 /// works. As usual, a `BufferCollectionToken.Sync` can be started after any
3736 /// `BufferCollectionToken.Duplicate` messages have been sent via the newly
3737 /// created token, to also sync those additional tokens to sysmem using a
3738 /// single round-trip.
3739 ///
3740 /// All table fields are currently required.
3741 ///
3742 /// + request `rights_attentuation_mask` This allows attenuating the VMO
3743 /// rights of the subtree. These values for `rights_attenuation_mask`
3744 /// result in no attenuation (note that 0 is not on this list):
3745 /// + ZX_RIGHT_SAME_RIGHTS (preferred)
3746 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
3747 /// + request `token_request` The server end of the `BufferCollectionToken`
3748 /// channel. The client retains the client end.
3749 pub fn r#attach_token(
3750 &self,
3751 mut payload: BufferCollectionAttachTokenRequest,
3752 ) -> Result<(), fidl::Error> {
3753 BufferCollectionProxyInterface::r#attach_token(self, payload)
3754 }
3755
3756 /// Set up an eventpair to be signalled (`ZX_EVENTPAIR_PEER_CLOSED`) when
3757 /// buffers have been allocated and only the specified number of buffers (or
3758 /// fewer) remain in the buffer collection.
3759 ///
3760 /// [`fuchsia.sysmem2/BufferCollection.AttachLifetimeTracking`] allows a
3761 /// client to wait until an old buffer collection is fully or mostly
3762 /// deallocated before attempting allocation of a new buffer collection. The
3763 /// eventpair is only signalled when the buffers of this collection have
3764 /// been fully deallocated (not just un-referenced by clients, but all the
3765 /// memory consumed by those buffers has been fully reclaimed/recycled), or
3766 /// when allocation or logical allocation fails for the tree or subtree
3767 /// including this [`fuchsia.sysmem2/BufferCollection`].
3768 ///
3769 /// The eventpair won't be signalled until allocation or logical allocation
3770 /// has completed; until then, the collection's current buffer count is
3771 /// ignored.
3772 ///
3773 /// If logical allocation fails for an attached subtree (using
3774 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]), the server end of the
3775 /// eventpair will close during that failure regardless of the number of
3776 /// buffers potenitally allocated in the overall buffer collection. This is
3777 /// for logical allocation consistency with normal allocation.
3778 ///
3779 /// The lifetime signalled by this event includes asynchronous cleanup of
3780 /// allocated buffers, and this asynchronous cleanup cannot occur until all
3781 /// holders of VMO handles to the buffers have closed those VMO handles.
3782 /// Therefore, clients should take care not to become blocked forever
3783 /// waiting for `ZX_EVENTPAIR_PEER_CLOSED` to be signalled if any of the
3784 /// participants using the logical buffer collection (including the waiter
3785 /// itself) are less trusted, less reliable, or potentially blocked by the
3786 /// wait itself. Waiting asynchronously is recommended. Setting a deadline
3787 /// for the client wait may be prudent, depending on details of how the
3788 /// collection and/or its VMOs are used or shared. Failure to allocate a
3789 /// new/replacement buffer collection is better than getting stuck forever.
3790 ///
3791 /// The sysmem server itself intentionally does not perform any waiting on
3792 /// already-failed collections' VMOs to finish cleaning up before attempting
3793 /// a new allocation, and the sysmem server intentionally doesn't retry
3794 /// allocation if a new allocation fails due to out of memory, even if that
3795 /// failure is potentially due to continued existence of an old collection's
3796 /// VMOs. This `AttachLifetimeTracking` message is how an initiator can
3797 /// mitigate too much overlap of old VMO lifetimes with new VMO lifetimes,
3798 /// as long as the waiting client is careful to not create a deadlock.
3799 ///
3800 /// Continued existence of old collections that are still cleaning up is not
3801 /// the only reason that a new allocation may fail due to insufficient
3802 /// memory, even if the new allocation is allocating physically contiguous
3803 /// buffers. Overall system memory pressure can also be the cause of failure
3804 /// to allocate a new collection. See also
3805 /// [`fuchsia.memorypressure/Provider`].
3806 ///
3807 /// `AttachLifetimeTracking` is meant to be compatible with other protocols
3808 /// with a similar `AttachLifetimeTracking` message; duplicates of the same
3809 /// `eventpair` handle (server end) can be sent via more than one
3810 /// `AttachLifetimeTracking` message to different protocols, and the
3811 /// `ZX_EVENTPAIR_PEER_CLOSED` will be signalled for the client end when all
3812 /// the conditions are met (all holders of duplicates have closed their
3813 /// server end handle(s)). Also, thanks to how eventpair endponts work, the
3814 /// client end can (also) be duplicated without preventing the
3815 /// `ZX_EVENTPAIR_PEER_CLOSED` signal.
3816 ///
3817 /// The server intentionally doesn't "trust" any signals set on the
3818 /// `server_end`. This mechanism intentionally uses only
3819 /// `ZX_EVENTPAIR_PEER_CLOSED` set on the client end, which can't be set
3820 /// "early", and is only set when all handles to the server end eventpair
3821 /// are closed. No meaning is associated with any of the other signals, and
3822 /// clients should ignore any other signal bits on either end of the
3823 /// `eventpair`.
3824 ///
3825 /// The `server_end` may lack `ZX_RIGHT_SIGNAL` or `ZX_RIGHT_SIGNAL_PEER`,
3826 /// but must have `ZX_RIGHT_DUPLICATE` (and must have `ZX_RIGHT_TRANSFER` to
3827 /// transfer without causing `BufferCollection` channel failure).
3828 ///
3829 /// All table fields are currently required.
3830 ///
3831 /// + request `server_end` This eventpair handle will be closed by the
3832 /// sysmem server when buffers have been allocated initially and the
3833 /// number of buffers is then less than or equal to `buffers_remaining`.
3834 /// + request `buffers_remaining` Wait for all but `buffers_remaining` (or
3835 /// fewer) buffers to be fully deallocated. A number greater than zero can
3836 /// be useful in situations where a known number of buffers are
3837 /// intentionally not closed so that the data can continue to be used,
3838 /// such as for keeping the last available video frame displayed in the UI
3839 /// even if the video stream was using protected output buffers. It's
3840 /// outside the scope of the `BufferCollection` interface (at least for
3841 /// now) to determine how many buffers may be held without closing, but
3842 /// it'll typically be in the range 0-2.
3843 pub fn r#attach_lifetime_tracking(
3844 &self,
3845 mut payload: BufferCollectionAttachLifetimeTrackingRequest,
3846 ) -> Result<(), fidl::Error> {
3847 BufferCollectionProxyInterface::r#attach_lifetime_tracking(self, payload)
3848 }
3849}
3850
3851impl BufferCollectionProxyInterface for BufferCollectionProxy {
3852 type SyncResponseFut =
3853 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
3854 fn r#sync(&self) -> Self::SyncResponseFut {
3855 fn _decode(
3856 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
3857 ) -> Result<(), fidl::Error> {
3858 let _response = fidl::client::decode_transaction_body::<
3859 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
3860 fidl::encoding::DefaultFuchsiaResourceDialect,
3861 0x11ac2555cf575b54,
3862 >(_buf?)?
3863 .into_result::<BufferCollectionMarker>("sync")?;
3864 Ok(_response)
3865 }
3866 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
3867 (),
3868 0x11ac2555cf575b54,
3869 fidl::encoding::DynamicFlags::FLEXIBLE,
3870 _decode,
3871 )
3872 }
3873
3874 fn r#release(&self) -> Result<(), fidl::Error> {
3875 self.client.send::<fidl::encoding::EmptyPayload>(
3876 (),
3877 0x6a5cae7d6d6e04c6,
3878 fidl::encoding::DynamicFlags::FLEXIBLE,
3879 )
3880 }
3881
3882 fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
3883 self.client.send::<NodeSetNameRequest>(
3884 payload,
3885 0xb41f1624f48c1e9,
3886 fidl::encoding::DynamicFlags::FLEXIBLE,
3887 )
3888 }
3889
3890 fn r#set_debug_client_info(
3891 &self,
3892 mut payload: &NodeSetDebugClientInfoRequest,
3893 ) -> Result<(), fidl::Error> {
3894 self.client.send::<NodeSetDebugClientInfoRequest>(
3895 payload,
3896 0x5cde8914608d99b1,
3897 fidl::encoding::DynamicFlags::FLEXIBLE,
3898 )
3899 }
3900
3901 fn r#set_debug_timeout_log_deadline(
3902 &self,
3903 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
3904 ) -> Result<(), fidl::Error> {
3905 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
3906 payload,
3907 0x716b0af13d5c0806,
3908 fidl::encoding::DynamicFlags::FLEXIBLE,
3909 )
3910 }
3911
3912 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
3913 self.client.send::<fidl::encoding::EmptyPayload>(
3914 (),
3915 0x5209c77415b4dfad,
3916 fidl::encoding::DynamicFlags::FLEXIBLE,
3917 )
3918 }
3919
3920 type GetNodeRefResponseFut = fidl::client::QueryResponseFut<
3921 NodeGetNodeRefResponse,
3922 fidl::encoding::DefaultFuchsiaResourceDialect,
3923 >;
3924 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
3925 fn _decode(
3926 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
3927 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
3928 let _response = fidl::client::decode_transaction_body::<
3929 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
3930 fidl::encoding::DefaultFuchsiaResourceDialect,
3931 0x5b3d0e51614df053,
3932 >(_buf?)?
3933 .into_result::<BufferCollectionMarker>("get_node_ref")?;
3934 Ok(_response)
3935 }
3936 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
3937 (),
3938 0x5b3d0e51614df053,
3939 fidl::encoding::DynamicFlags::FLEXIBLE,
3940 _decode,
3941 )
3942 }
3943
3944 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
3945 NodeIsAlternateForResult,
3946 fidl::encoding::DefaultFuchsiaResourceDialect,
3947 >;
3948 fn r#is_alternate_for(
3949 &self,
3950 mut payload: NodeIsAlternateForRequest,
3951 ) -> Self::IsAlternateForResponseFut {
3952 fn _decode(
3953 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
3954 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
3955 let _response = fidl::client::decode_transaction_body::<
3956 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
3957 fidl::encoding::DefaultFuchsiaResourceDialect,
3958 0x3a58e00157e0825,
3959 >(_buf?)?
3960 .into_result::<BufferCollectionMarker>("is_alternate_for")?;
3961 Ok(_response.map(|x| x))
3962 }
3963 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
3964 &mut payload,
3965 0x3a58e00157e0825,
3966 fidl::encoding::DynamicFlags::FLEXIBLE,
3967 _decode,
3968 )
3969 }
3970
3971 type GetBufferCollectionIdResponseFut = fidl::client::QueryResponseFut<
3972 NodeGetBufferCollectionIdResponse,
3973 fidl::encoding::DefaultFuchsiaResourceDialect,
3974 >;
3975 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut {
3976 fn _decode(
3977 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
3978 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
3979 let _response = fidl::client::decode_transaction_body::<
3980 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
3981 fidl::encoding::DefaultFuchsiaResourceDialect,
3982 0x77d19a494b78ba8c,
3983 >(_buf?)?
3984 .into_result::<BufferCollectionMarker>("get_buffer_collection_id")?;
3985 Ok(_response)
3986 }
3987 self.client.send_query_and_decode::<
3988 fidl::encoding::EmptyPayload,
3989 NodeGetBufferCollectionIdResponse,
3990 >(
3991 (),
3992 0x77d19a494b78ba8c,
3993 fidl::encoding::DynamicFlags::FLEXIBLE,
3994 _decode,
3995 )
3996 }
3997
3998 fn r#set_weak(&self) -> Result<(), fidl::Error> {
3999 self.client.send::<fidl::encoding::EmptyPayload>(
4000 (),
4001 0x22dd3ea514eeffe1,
4002 fidl::encoding::DynamicFlags::FLEXIBLE,
4003 )
4004 }
4005
4006 fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
4007 self.client.send::<NodeSetWeakOkRequest>(
4008 &mut payload,
4009 0x38a44fc4d7724be9,
4010 fidl::encoding::DynamicFlags::FLEXIBLE,
4011 )
4012 }
4013
4014 fn r#attach_node_tracking(
4015 &self,
4016 mut payload: NodeAttachNodeTrackingRequest,
4017 ) -> Result<(), fidl::Error> {
4018 self.client.send::<NodeAttachNodeTrackingRequest>(
4019 &mut payload,
4020 0x3f22f2a293d3cdac,
4021 fidl::encoding::DynamicFlags::FLEXIBLE,
4022 )
4023 }
4024
4025 fn r#set_constraints(
4026 &self,
4027 mut payload: BufferCollectionSetConstraintsRequest,
4028 ) -> Result<(), fidl::Error> {
4029 self.client.send::<BufferCollectionSetConstraintsRequest>(
4030 &mut payload,
4031 0x1fde0f19d650197b,
4032 fidl::encoding::DynamicFlags::FLEXIBLE,
4033 )
4034 }
4035
4036 type WaitForAllBuffersAllocatedResponseFut = fidl::client::QueryResponseFut<
4037 BufferCollectionWaitForAllBuffersAllocatedResult,
4038 fidl::encoding::DefaultFuchsiaResourceDialect,
4039 >;
4040 fn r#wait_for_all_buffers_allocated(&self) -> Self::WaitForAllBuffersAllocatedResponseFut {
4041 fn _decode(
4042 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
4043 ) -> Result<BufferCollectionWaitForAllBuffersAllocatedResult, fidl::Error> {
4044 let _response = fidl::client::decode_transaction_body::<
4045 fidl::encoding::FlexibleResultType<
4046 BufferCollectionWaitForAllBuffersAllocatedResponse,
4047 Error,
4048 >,
4049 fidl::encoding::DefaultFuchsiaResourceDialect,
4050 0x62300344b61404e,
4051 >(_buf?)?
4052 .into_result::<BufferCollectionMarker>("wait_for_all_buffers_allocated")?;
4053 Ok(_response.map(|x| x))
4054 }
4055 self.client.send_query_and_decode::<
4056 fidl::encoding::EmptyPayload,
4057 BufferCollectionWaitForAllBuffersAllocatedResult,
4058 >(
4059 (),
4060 0x62300344b61404e,
4061 fidl::encoding::DynamicFlags::FLEXIBLE,
4062 _decode,
4063 )
4064 }
4065
4066 type CheckAllBuffersAllocatedResponseFut = fidl::client::QueryResponseFut<
4067 BufferCollectionCheckAllBuffersAllocatedResult,
4068 fidl::encoding::DefaultFuchsiaResourceDialect,
4069 >;
4070 fn r#check_all_buffers_allocated(&self) -> Self::CheckAllBuffersAllocatedResponseFut {
4071 fn _decode(
4072 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
4073 ) -> Result<BufferCollectionCheckAllBuffersAllocatedResult, fidl::Error> {
4074 let _response = fidl::client::decode_transaction_body::<
4075 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
4076 fidl::encoding::DefaultFuchsiaResourceDialect,
4077 0x35a5fe77ce939c10,
4078 >(_buf?)?
4079 .into_result::<BufferCollectionMarker>("check_all_buffers_allocated")?;
4080 Ok(_response.map(|x| x))
4081 }
4082 self.client.send_query_and_decode::<
4083 fidl::encoding::EmptyPayload,
4084 BufferCollectionCheckAllBuffersAllocatedResult,
4085 >(
4086 (),
4087 0x35a5fe77ce939c10,
4088 fidl::encoding::DynamicFlags::FLEXIBLE,
4089 _decode,
4090 )
4091 }
4092
4093 fn r#attach_token(
4094 &self,
4095 mut payload: BufferCollectionAttachTokenRequest,
4096 ) -> Result<(), fidl::Error> {
4097 self.client.send::<BufferCollectionAttachTokenRequest>(
4098 &mut payload,
4099 0x46ac7d0008492982,
4100 fidl::encoding::DynamicFlags::FLEXIBLE,
4101 )
4102 }
4103
4104 fn r#attach_lifetime_tracking(
4105 &self,
4106 mut payload: BufferCollectionAttachLifetimeTrackingRequest,
4107 ) -> Result<(), fidl::Error> {
4108 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
4109 &mut payload,
4110 0x3ecb510113116dcf,
4111 fidl::encoding::DynamicFlags::FLEXIBLE,
4112 )
4113 }
4114}
4115
4116pub struct BufferCollectionEventStream {
4117 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
4118}
4119
4120impl std::marker::Unpin for BufferCollectionEventStream {}
4121
4122impl futures::stream::FusedStream for BufferCollectionEventStream {
4123 fn is_terminated(&self) -> bool {
4124 self.event_receiver.is_terminated()
4125 }
4126}
4127
4128impl futures::Stream for BufferCollectionEventStream {
4129 type Item = Result<BufferCollectionEvent, fidl::Error>;
4130
4131 fn poll_next(
4132 mut self: std::pin::Pin<&mut Self>,
4133 cx: &mut std::task::Context<'_>,
4134 ) -> std::task::Poll<Option<Self::Item>> {
4135 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
4136 &mut self.event_receiver,
4137 cx
4138 )?) {
4139 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionEvent::decode(buf))),
4140 None => std::task::Poll::Ready(None),
4141 }
4142 }
4143}
4144
4145#[derive(Debug)]
4146pub enum BufferCollectionEvent {
4147 #[non_exhaustive]
4148 _UnknownEvent {
4149 /// Ordinal of the event that was sent.
4150 ordinal: u64,
4151 },
4152}
4153
4154impl BufferCollectionEvent {
4155 /// Decodes a message buffer as a [`BufferCollectionEvent`].
4156 fn decode(
4157 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
4158 ) -> Result<BufferCollectionEvent, fidl::Error> {
4159 let (bytes, _handles) = buf.split_mut();
4160 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
4161 debug_assert_eq!(tx_header.tx_id, 0);
4162 match tx_header.ordinal {
4163 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
4164 Ok(BufferCollectionEvent::_UnknownEvent { ordinal: tx_header.ordinal })
4165 }
4166 _ => Err(fidl::Error::UnknownOrdinal {
4167 ordinal: tx_header.ordinal,
4168 protocol_name:
4169 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
4170 }),
4171 }
4172 }
4173}
4174
4175/// A Stream of incoming requests for fuchsia.sysmem2/BufferCollection.
4176pub struct BufferCollectionRequestStream {
4177 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
4178 is_terminated: bool,
4179}
4180
4181impl std::marker::Unpin for BufferCollectionRequestStream {}
4182
4183impl futures::stream::FusedStream for BufferCollectionRequestStream {
4184 fn is_terminated(&self) -> bool {
4185 self.is_terminated
4186 }
4187}
4188
4189impl fidl::endpoints::RequestStream for BufferCollectionRequestStream {
4190 type Protocol = BufferCollectionMarker;
4191 type ControlHandle = BufferCollectionControlHandle;
4192
4193 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
4194 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
4195 }
4196
4197 fn control_handle(&self) -> Self::ControlHandle {
4198 BufferCollectionControlHandle { inner: self.inner.clone() }
4199 }
4200
4201 fn into_inner(
4202 self,
4203 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
4204 {
4205 (self.inner, self.is_terminated)
4206 }
4207
4208 fn from_inner(
4209 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
4210 is_terminated: bool,
4211 ) -> Self {
4212 Self { inner, is_terminated }
4213 }
4214}
4215
4216impl futures::Stream for BufferCollectionRequestStream {
4217 type Item = Result<BufferCollectionRequest, fidl::Error>;
4218
4219 fn poll_next(
4220 mut self: std::pin::Pin<&mut Self>,
4221 cx: &mut std::task::Context<'_>,
4222 ) -> std::task::Poll<Option<Self::Item>> {
4223 let this = &mut *self;
4224 if this.inner.check_shutdown(cx) {
4225 this.is_terminated = true;
4226 return std::task::Poll::Ready(None);
4227 }
4228 if this.is_terminated {
4229 panic!("polled BufferCollectionRequestStream after completion");
4230 }
4231 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
4232 |bytes, handles| {
4233 match this.inner.channel().read_etc(cx, bytes, handles) {
4234 std::task::Poll::Ready(Ok(())) => {}
4235 std::task::Poll::Pending => return std::task::Poll::Pending,
4236 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
4237 this.is_terminated = true;
4238 return std::task::Poll::Ready(None);
4239 }
4240 std::task::Poll::Ready(Err(e)) => {
4241 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
4242 e.into(),
4243 ))));
4244 }
4245 }
4246
4247 // A message has been received from the channel
4248 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
4249
4250 std::task::Poll::Ready(Some(match header.ordinal {
4251 0x11ac2555cf575b54 => {
4252 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4253 let mut req = fidl::new_empty!(
4254 fidl::encoding::EmptyPayload,
4255 fidl::encoding::DefaultFuchsiaResourceDialect
4256 );
4257 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4258 let control_handle =
4259 BufferCollectionControlHandle { inner: this.inner.clone() };
4260 Ok(BufferCollectionRequest::Sync {
4261 responder: BufferCollectionSyncResponder {
4262 control_handle: std::mem::ManuallyDrop::new(control_handle),
4263 tx_id: header.tx_id,
4264 },
4265 })
4266 }
4267 0x6a5cae7d6d6e04c6 => {
4268 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4269 let mut req = fidl::new_empty!(
4270 fidl::encoding::EmptyPayload,
4271 fidl::encoding::DefaultFuchsiaResourceDialect
4272 );
4273 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4274 let control_handle =
4275 BufferCollectionControlHandle { inner: this.inner.clone() };
4276 Ok(BufferCollectionRequest::Release { control_handle })
4277 }
4278 0xb41f1624f48c1e9 => {
4279 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4280 let mut req = fidl::new_empty!(
4281 NodeSetNameRequest,
4282 fidl::encoding::DefaultFuchsiaResourceDialect
4283 );
4284 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
4285 let control_handle =
4286 BufferCollectionControlHandle { inner: this.inner.clone() };
4287 Ok(BufferCollectionRequest::SetName { payload: req, control_handle })
4288 }
4289 0x5cde8914608d99b1 => {
4290 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4291 let mut req = fidl::new_empty!(
4292 NodeSetDebugClientInfoRequest,
4293 fidl::encoding::DefaultFuchsiaResourceDialect
4294 );
4295 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
4296 let control_handle =
4297 BufferCollectionControlHandle { inner: this.inner.clone() };
4298 Ok(BufferCollectionRequest::SetDebugClientInfo {
4299 payload: req,
4300 control_handle,
4301 })
4302 }
4303 0x716b0af13d5c0806 => {
4304 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4305 let mut req = fidl::new_empty!(
4306 NodeSetDebugTimeoutLogDeadlineRequest,
4307 fidl::encoding::DefaultFuchsiaResourceDialect
4308 );
4309 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
4310 let control_handle =
4311 BufferCollectionControlHandle { inner: this.inner.clone() };
4312 Ok(BufferCollectionRequest::SetDebugTimeoutLogDeadline {
4313 payload: req,
4314 control_handle,
4315 })
4316 }
4317 0x5209c77415b4dfad => {
4318 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4319 let mut req = fidl::new_empty!(
4320 fidl::encoding::EmptyPayload,
4321 fidl::encoding::DefaultFuchsiaResourceDialect
4322 );
4323 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4324 let control_handle =
4325 BufferCollectionControlHandle { inner: this.inner.clone() };
4326 Ok(BufferCollectionRequest::SetVerboseLogging { control_handle })
4327 }
4328 0x5b3d0e51614df053 => {
4329 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4330 let mut req = fidl::new_empty!(
4331 fidl::encoding::EmptyPayload,
4332 fidl::encoding::DefaultFuchsiaResourceDialect
4333 );
4334 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4335 let control_handle =
4336 BufferCollectionControlHandle { inner: this.inner.clone() };
4337 Ok(BufferCollectionRequest::GetNodeRef {
4338 responder: BufferCollectionGetNodeRefResponder {
4339 control_handle: std::mem::ManuallyDrop::new(control_handle),
4340 tx_id: header.tx_id,
4341 },
4342 })
4343 }
4344 0x3a58e00157e0825 => {
4345 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4346 let mut req = fidl::new_empty!(
4347 NodeIsAlternateForRequest,
4348 fidl::encoding::DefaultFuchsiaResourceDialect
4349 );
4350 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
4351 let control_handle =
4352 BufferCollectionControlHandle { inner: this.inner.clone() };
4353 Ok(BufferCollectionRequest::IsAlternateFor {
4354 payload: req,
4355 responder: BufferCollectionIsAlternateForResponder {
4356 control_handle: std::mem::ManuallyDrop::new(control_handle),
4357 tx_id: header.tx_id,
4358 },
4359 })
4360 }
4361 0x77d19a494b78ba8c => {
4362 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4363 let mut req = fidl::new_empty!(
4364 fidl::encoding::EmptyPayload,
4365 fidl::encoding::DefaultFuchsiaResourceDialect
4366 );
4367 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4368 let control_handle =
4369 BufferCollectionControlHandle { inner: this.inner.clone() };
4370 Ok(BufferCollectionRequest::GetBufferCollectionId {
4371 responder: BufferCollectionGetBufferCollectionIdResponder {
4372 control_handle: std::mem::ManuallyDrop::new(control_handle),
4373 tx_id: header.tx_id,
4374 },
4375 })
4376 }
4377 0x22dd3ea514eeffe1 => {
4378 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4379 let mut req = fidl::new_empty!(
4380 fidl::encoding::EmptyPayload,
4381 fidl::encoding::DefaultFuchsiaResourceDialect
4382 );
4383 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4384 let control_handle =
4385 BufferCollectionControlHandle { inner: this.inner.clone() };
4386 Ok(BufferCollectionRequest::SetWeak { control_handle })
4387 }
4388 0x38a44fc4d7724be9 => {
4389 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4390 let mut req = fidl::new_empty!(
4391 NodeSetWeakOkRequest,
4392 fidl::encoding::DefaultFuchsiaResourceDialect
4393 );
4394 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetWeakOkRequest>(&header, _body_bytes, handles, &mut req)?;
4395 let control_handle =
4396 BufferCollectionControlHandle { inner: this.inner.clone() };
4397 Ok(BufferCollectionRequest::SetWeakOk { payload: req, control_handle })
4398 }
4399 0x3f22f2a293d3cdac => {
4400 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4401 let mut req = fidl::new_empty!(
4402 NodeAttachNodeTrackingRequest,
4403 fidl::encoding::DefaultFuchsiaResourceDialect
4404 );
4405 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeAttachNodeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
4406 let control_handle =
4407 BufferCollectionControlHandle { inner: this.inner.clone() };
4408 Ok(BufferCollectionRequest::AttachNodeTracking {
4409 payload: req,
4410 control_handle,
4411 })
4412 }
4413 0x1fde0f19d650197b => {
4414 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4415 let mut req = fidl::new_empty!(
4416 BufferCollectionSetConstraintsRequest,
4417 fidl::encoding::DefaultFuchsiaResourceDialect
4418 );
4419 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionSetConstraintsRequest>(&header, _body_bytes, handles, &mut req)?;
4420 let control_handle =
4421 BufferCollectionControlHandle { inner: this.inner.clone() };
4422 Ok(BufferCollectionRequest::SetConstraints { payload: req, control_handle })
4423 }
4424 0x62300344b61404e => {
4425 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4426 let mut req = fidl::new_empty!(
4427 fidl::encoding::EmptyPayload,
4428 fidl::encoding::DefaultFuchsiaResourceDialect
4429 );
4430 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4431 let control_handle =
4432 BufferCollectionControlHandle { inner: this.inner.clone() };
4433 Ok(BufferCollectionRequest::WaitForAllBuffersAllocated {
4434 responder: BufferCollectionWaitForAllBuffersAllocatedResponder {
4435 control_handle: std::mem::ManuallyDrop::new(control_handle),
4436 tx_id: header.tx_id,
4437 },
4438 })
4439 }
4440 0x35a5fe77ce939c10 => {
4441 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
4442 let mut req = fidl::new_empty!(
4443 fidl::encoding::EmptyPayload,
4444 fidl::encoding::DefaultFuchsiaResourceDialect
4445 );
4446 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
4447 let control_handle =
4448 BufferCollectionControlHandle { inner: this.inner.clone() };
4449 Ok(BufferCollectionRequest::CheckAllBuffersAllocated {
4450 responder: BufferCollectionCheckAllBuffersAllocatedResponder {
4451 control_handle: std::mem::ManuallyDrop::new(control_handle),
4452 tx_id: header.tx_id,
4453 },
4454 })
4455 }
4456 0x46ac7d0008492982 => {
4457 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4458 let mut req = fidl::new_empty!(
4459 BufferCollectionAttachTokenRequest,
4460 fidl::encoding::DefaultFuchsiaResourceDialect
4461 );
4462 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachTokenRequest>(&header, _body_bytes, handles, &mut req)?;
4463 let control_handle =
4464 BufferCollectionControlHandle { inner: this.inner.clone() };
4465 Ok(BufferCollectionRequest::AttachToken { payload: req, control_handle })
4466 }
4467 0x3ecb510113116dcf => {
4468 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
4469 let mut req = fidl::new_empty!(
4470 BufferCollectionAttachLifetimeTrackingRequest,
4471 fidl::encoding::DefaultFuchsiaResourceDialect
4472 );
4473 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachLifetimeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
4474 let control_handle =
4475 BufferCollectionControlHandle { inner: this.inner.clone() };
4476 Ok(BufferCollectionRequest::AttachLifetimeTracking {
4477 payload: req,
4478 control_handle,
4479 })
4480 }
4481 _ if header.tx_id == 0
4482 && header
4483 .dynamic_flags()
4484 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
4485 {
4486 Ok(BufferCollectionRequest::_UnknownMethod {
4487 ordinal: header.ordinal,
4488 control_handle: BufferCollectionControlHandle {
4489 inner: this.inner.clone(),
4490 },
4491 method_type: fidl::MethodType::OneWay,
4492 })
4493 }
4494 _ if header
4495 .dynamic_flags()
4496 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
4497 {
4498 this.inner.send_framework_err(
4499 fidl::encoding::FrameworkErr::UnknownMethod,
4500 header.tx_id,
4501 header.ordinal,
4502 header.dynamic_flags(),
4503 (bytes, handles),
4504 )?;
4505 Ok(BufferCollectionRequest::_UnknownMethod {
4506 ordinal: header.ordinal,
4507 control_handle: BufferCollectionControlHandle {
4508 inner: this.inner.clone(),
4509 },
4510 method_type: fidl::MethodType::TwoWay,
4511 })
4512 }
4513 _ => Err(fidl::Error::UnknownOrdinal {
4514 ordinal: header.ordinal,
4515 protocol_name:
4516 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
4517 }),
4518 }))
4519 },
4520 )
4521 }
4522}
4523
4524/// [`fuchsia.sysmem2/BufferCollection`] is a connection directly from a
4525/// participant to sysmem re. a buffer collection; often the buffer collection
4526/// is shared with other participants which have their own `BufferCollection`
4527/// client end(s) associated with the same buffer collection. In other words,
4528/// an instance of the `BufferCollection` interface is a view of a buffer
4529/// collection, not the buffer collection itself.
4530///
4531/// The `BufferCollection` connection exists to facilitate async indication of
4532/// when the buffer collection has been populated with buffers.
4533///
4534/// Also, the channel's closure by the sysmem server is an indication to the
4535/// client that the client should close all VMO handles that were obtained from
4536/// the `BufferCollection` ASAP.
4537///
4538/// Some buffer collections can use enough memory that it can be worth avoiding
4539/// allocation overlap (in time) using
4540/// [`fuchsia.sysmem2/BufferCollection.AttachLifetimeTracking`] so that the
4541/// initiator can tell when enough buffers of the buffer collection have been
4542/// fully deallocated prior to the initiator allocating a new buffer collection.
4543///
4544/// Epitaphs are not used in this protocol.
4545#[derive(Debug)]
4546pub enum BufferCollectionRequest {
4547 /// Ensure that previous messages have been received server side. This is
4548 /// particularly useful after previous messages that created new tokens,
4549 /// because a token must be known to the sysmem server before sending the
4550 /// token to another participant.
4551 ///
4552 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
4553 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
4554 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
4555 /// to mitigate the possibility of a hostile/fake
4556 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
4557 /// Another way is to pass the token to
4558 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
4559 /// the token as part of exchanging it for a
4560 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
4561 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
4562 /// of stalling.
4563 ///
4564 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
4565 /// and then starting and completing a `Sync`, it's then safe to send the
4566 /// `BufferCollectionToken` client ends to other participants knowing the
4567 /// server will recognize the tokens when they're sent by the other
4568 /// participants to sysmem in a
4569 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
4570 /// efficient way to create tokens while avoiding unnecessary round trips.
4571 ///
4572 /// Other options include waiting for each
4573 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
4574 /// individually (using separate call to `Sync` after each), or calling
4575 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
4576 /// converted to a `BufferCollection` via
4577 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
4578 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
4579 /// the sync step and can create multiple tokens at once.
4580 Sync { responder: BufferCollectionSyncResponder },
4581 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
4582 ///
4583 /// Normally a participant will convert a `BufferCollectionToken` into a
4584 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
4585 /// `Release` via the token (and then close the channel immediately or
4586 /// shortly later in response to server closing the server end), which
4587 /// avoids causing buffer collection failure. Without a prior `Release`,
4588 /// closing the `BufferCollectionToken` client end will cause buffer
4589 /// collection failure.
4590 ///
4591 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
4592 ///
4593 /// By default the server handles unexpected closure of a
4594 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
4595 /// first) by failing the buffer collection. Partly this is to expedite
4596 /// closing VMO handles to reclaim memory when any participant fails. If a
4597 /// participant would like to cleanly close a `BufferCollection` without
4598 /// causing buffer collection failure, the participant can send `Release`
4599 /// before closing the `BufferCollection` client end. The `Release` can
4600 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
4601 /// buffer collection won't require constraints from this node in order to
4602 /// allocate. If after `SetConstraints`, the constraints are retained and
4603 /// aggregated, despite the lack of `BufferCollection` connection at the
4604 /// time of constraints aggregation.
4605 ///
4606 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
4607 ///
4608 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
4609 /// end (without `Release` first) will trigger failure of the buffer
4610 /// collection. To close a `BufferCollectionTokenGroup` channel without
4611 /// failing the buffer collection, ensure that AllChildrenPresent() has been
4612 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
4613 /// client end.
4614 ///
4615 /// If `Release` occurs before
4616 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
4617 /// buffer collection will fail (triggered by reception of `Release` without
4618 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
4619 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
4620 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
4621 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
4622 /// close requires `AllChildrenPresent` (if not already sent), then
4623 /// `Release`, then close client end.
4624 ///
4625 /// If `Release` occurs after `AllChildrenPresent`, the children and all
4626 /// their constraints remain intact (just as they would if the
4627 /// `BufferCollectionTokenGroup` channel had remained open), and the client
4628 /// end close doesn't trigger buffer collection failure.
4629 ///
4630 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
4631 ///
4632 /// For brevity, the per-channel-protocol paragraphs above ignore the
4633 /// separate failure domain created by
4634 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
4635 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
4636 /// unexpectedly closes (without `Release` first) and that client end is
4637 /// under a failure domain, instead of failing the whole buffer collection,
4638 /// the failure domain is failed, but the buffer collection itself is
4639 /// isolated from failure of the failure domain. Such failure domains can be
4640 /// nested, in which case only the inner-most failure domain in which the
4641 /// `Node` resides fails.
4642 Release { control_handle: BufferCollectionControlHandle },
4643 /// Set a name for VMOs in this buffer collection.
4644 ///
4645 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
4646 /// will be truncated to fit. The name of the vmo will be suffixed with the
4647 /// buffer index within the collection (if the suffix fits within
4648 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
4649 /// listed in the inspect data.
4650 ///
4651 /// The name only affects VMOs allocated after the name is set; this call
4652 /// does not rename existing VMOs. If multiple clients set different names
4653 /// then the larger priority value will win. Setting a new name with the
4654 /// same priority as a prior name doesn't change the name.
4655 ///
4656 /// All table fields are currently required.
4657 ///
4658 /// + request `priority` The name is only set if this is the first `SetName`
4659 /// or if `priority` is greater than any previous `priority` value in
4660 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
4661 /// + request `name` The name for VMOs created under this buffer collection.
4662 SetName { payload: NodeSetNameRequest, control_handle: BufferCollectionControlHandle },
4663 /// Set information about the current client that can be used by sysmem to
4664 /// help diagnose leaking memory and allocation stalls waiting for a
4665 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
4666 ///
4667 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
4668 /// `Node`(s) derived from this `Node`, unless overriden by
4669 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
4670 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
4671 ///
4672 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
4673 /// `Allocator` is the most efficient way to ensure that all
4674 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
4675 /// set, and is also more efficient than separately sending the same debug
4676 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
4677 /// created [`fuchsia.sysmem2/Node`].
4678 ///
4679 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
4680 /// indicate which client is closing their channel first, leading to subtree
4681 /// failure (which can be normal if the purpose of the subtree is over, but
4682 /// if happening earlier than expected, the client-channel-specific name can
4683 /// help diagnose where the failure is first coming from, from sysmem's
4684 /// point of view).
4685 ///
4686 /// All table fields are currently required.
4687 ///
4688 /// + request `name` This can be an arbitrary string, but the current
4689 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
4690 /// + request `id` This can be an arbitrary id, but the current process ID
4691 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
4692 SetDebugClientInfo {
4693 payload: NodeSetDebugClientInfoRequest,
4694 control_handle: BufferCollectionControlHandle,
4695 },
4696 /// Sysmem logs a warning if sysmem hasn't seen
4697 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
4698 /// within 5 seconds after creation of a new collection.
4699 ///
4700 /// Clients can call this method to change when the log is printed. If
4701 /// multiple client set the deadline, it's unspecified which deadline will
4702 /// take effect.
4703 ///
4704 /// In most cases the default works well.
4705 ///
4706 /// All table fields are currently required.
4707 ///
4708 /// + request `deadline` The time at which sysmem will start trying to log
4709 /// the warning, unless all constraints are with sysmem by then.
4710 SetDebugTimeoutLogDeadline {
4711 payload: NodeSetDebugTimeoutLogDeadlineRequest,
4712 control_handle: BufferCollectionControlHandle,
4713 },
4714 /// This enables verbose logging for the buffer collection.
4715 ///
4716 /// Verbose logging includes constraints set via
4717 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
4718 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
4719 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
4720 /// the tree of `Node`(s).
4721 ///
4722 /// Normally sysmem prints only a single line complaint when aggregation
4723 /// fails, with just the specific detailed reason that aggregation failed,
4724 /// with little surrounding context. While this is often enough to diagnose
4725 /// a problem if only a small change was made and everything was working
4726 /// before the small change, it's often not particularly helpful for getting
4727 /// a new buffer collection to work for the first time. Especially with
4728 /// more complex trees of nodes, involving things like
4729 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
4730 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
4731 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
4732 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
4733 /// looks like and why it's failing a logical allocation, or why a tree or
4734 /// subtree is failing sooner than expected.
4735 ///
4736 /// The intent of the extra logging is to be acceptable from a performance
4737 /// point of view, under the assumption that verbose logging is only enabled
4738 /// on a low number of buffer collections. If we're not tracking down a bug,
4739 /// we shouldn't send this message.
4740 SetVerboseLogging { control_handle: BufferCollectionControlHandle },
4741 /// This gets a handle that can be used as a parameter to
4742 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
4743 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
4744 /// client obtained this handle from this `Node`.
4745 ///
4746 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
4747 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
4748 /// despite the two calls typically being on different channels.
4749 ///
4750 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
4751 ///
4752 /// All table fields are currently required.
4753 ///
4754 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
4755 /// different `Node` channel, to prove that the client obtained the handle
4756 /// from this `Node`.
4757 GetNodeRef { responder: BufferCollectionGetNodeRefResponder },
4758 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
4759 /// rooted at a different child token of a common parent
4760 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
4761 /// passed-in `node_ref`.
4762 ///
4763 /// This call is for assisting with admission control de-duplication, and
4764 /// with debugging.
4765 ///
4766 /// The `node_ref` must be obtained using
4767 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
4768 ///
4769 /// The `node_ref` can be a duplicated handle; it's not necessary to call
4770 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
4771 ///
4772 /// If a calling token may not actually be a valid token at all due to a
4773 /// potentially hostile/untrusted provider of the token, call
4774 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
4775 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
4776 /// never responds due to a calling token not being a real token (not really
4777 /// talking to sysmem). Another option is to call
4778 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
4779 /// which also validates the token along with converting it to a
4780 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
4781 ///
4782 /// All table fields are currently required.
4783 ///
4784 /// - response `is_alternate`
4785 /// - true: The first parent node in common between the calling node and
4786 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
4787 /// that the calling `Node` and the `node_ref` `Node` will not have both
4788 /// their constraints apply - rather sysmem will choose one or the other
4789 /// of the constraints - never both. This is because only one child of
4790 /// a `BufferCollectionTokenGroup` is selected during logical
4791 /// allocation, with only that one child's subtree contributing to
4792 /// constraints aggregation.
4793 /// - false: The first parent node in common between the calling `Node`
4794 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
4795 /// Currently, this means the first parent node in common is a
4796 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
4797 /// `Release`ed). This means that the calling `Node` and the `node_ref`
4798 /// `Node` may have both their constraints apply during constraints
4799 /// aggregation of the logical allocation, if both `Node`(s) are
4800 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
4801 /// this case, there is no `BufferCollectionTokenGroup` that will
4802 /// directly prevent the two `Node`(s) from both being selected and
4803 /// their constraints both aggregated, but even when false, one or both
4804 /// `Node`(s) may still be eliminated from consideration if one or both
4805 /// `Node`(s) has a direct or indirect parent
4806 /// `BufferCollectionTokenGroup` which selects a child subtree other
4807 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
4808 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
4809 /// associated with the same buffer collection as the calling `Node`.
4810 /// Another reason for this error is if the `node_ref` is an
4811 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
4812 /// a real `node_ref` obtained from `GetNodeRef`.
4813 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
4814 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
4815 /// the needed rights expected on a real `node_ref`.
4816 /// * No other failing status codes are returned by this call. However,
4817 /// sysmem may add additional codes in future, so the client should have
4818 /// sensible default handling for any failing status code.
4819 IsAlternateFor {
4820 payload: NodeIsAlternateForRequest,
4821 responder: BufferCollectionIsAlternateForResponder,
4822 },
4823 /// Get the buffer collection ID. This ID is also available from
4824 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
4825 /// within the collection).
4826 ///
4827 /// This call is mainly useful in situations where we can't convey a
4828 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
4829 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
4830 /// handle, which can be joined back up with a `BufferCollection` client end
4831 /// that was created via a different path. Prefer to convey a
4832 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
4833 ///
4834 /// Trusting a `buffer_collection_id` value from a source other than sysmem
4835 /// is analogous to trusting a koid value from a source other than zircon.
4836 /// Both should be avoided unless really necessary, and both require
4837 /// caution. In some situations it may be reasonable to refer to a
4838 /// pre-established `BufferCollection` by `buffer_collection_id` via a
4839 /// protocol for efficiency reasons, but an incoming value purporting to be
4840 /// a `buffer_collection_id` is not sufficient alone to justify granting the
4841 /// sender of the `buffer_collection_id` any capability. The sender must
4842 /// first prove to a receiver that the sender has/had a VMO or has/had a
4843 /// `BufferCollectionToken` to the same collection by sending a handle that
4844 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
4845 /// `buffer_collection_id` value. The receiver should take care to avoid
4846 /// assuming that a sender had a `BufferCollectionToken` in cases where the
4847 /// sender has only proven that the sender had a VMO.
4848 ///
4849 /// - response `buffer_collection_id` This ID is unique per buffer
4850 /// collection per boot. Each buffer is uniquely identified by the
4851 /// `buffer_collection_id` and `buffer_index` together.
4852 GetBufferCollectionId { responder: BufferCollectionGetBufferCollectionIdResponder },
4853 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
4854 /// created after this message to weak, which means that a client's `Node`
4855 /// client end (or a child created after this message) is not alone
4856 /// sufficient to keep allocated VMOs alive.
4857 ///
4858 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
4859 /// `close_weak_asap`.
4860 ///
4861 /// This message is only permitted before the `Node` becomes ready for
4862 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
4863 /// * `BufferCollectionToken`: any time
4864 /// * `BufferCollection`: before `SetConstraints`
4865 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
4866 ///
4867 /// Currently, no conversion from strong `Node` to weak `Node` after ready
4868 /// for allocation is provided, but a client can simulate that by creating
4869 /// an additional `Node` before allocation and setting that additional
4870 /// `Node` to weak, and then potentially at some point later sending
4871 /// `Release` and closing the client end of the client's strong `Node`, but
4872 /// keeping the client's weak `Node`.
4873 ///
4874 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
4875 /// collection failure (all `Node` client end(s) will see
4876 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
4877 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
4878 /// this situation until all `Node`(s) are ready for allocation. For initial
4879 /// allocation to succeed, at least one strong `Node` is required to exist
4880 /// at allocation time, but after that client receives VMO handles, that
4881 /// client can `BufferCollection.Release` and close the client end without
4882 /// causing this type of failure.
4883 ///
4884 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
4885 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
4886 /// separately as appropriate.
4887 SetWeak { control_handle: BufferCollectionControlHandle },
4888 /// This indicates to sysmem that the client is prepared to pay attention to
4889 /// `close_weak_asap`.
4890 ///
4891 /// If sent, this message must be before
4892 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
4893 ///
4894 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
4895 /// send this message before `WaitForAllBuffersAllocated`, or a parent
4896 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
4897 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
4898 /// trigger buffer collection failure.
4899 ///
4900 /// This message is necessary because weak sysmem VMOs have not always been
4901 /// a thing, so older clients are not aware of the need to pay attention to
4902 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
4903 /// sysmem weak VMO handles asap. By having this message and requiring
4904 /// participants to indicate their acceptance of this aspect of the overall
4905 /// protocol, we avoid situations where an older client is delivered a weak
4906 /// VMO without any way for sysmem to get that VMO to close quickly later
4907 /// (and on a per-buffer basis).
4908 ///
4909 /// A participant that doesn't handle `close_weak_asap` and also doesn't
4910 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
4911 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
4912 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
4913 /// same participant has a child/delegate which does retrieve VMOs, that
4914 /// child/delegate will need to send `SetWeakOk` before
4915 /// `WaitForAllBuffersAllocated`.
4916 ///
4917 /// + request `for_child_nodes_also` If present and true, this means direct
4918 /// child nodes of this node created after this message plus all
4919 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
4920 /// those nodes. Any child node of this node that was created before this
4921 /// message is not included. This setting is "sticky" in the sense that a
4922 /// subsequent `SetWeakOk` without this bool set to true does not reset
4923 /// the server-side bool. If this creates a problem for a participant, a
4924 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
4925 /// tokens instead, as appropriate. A participant should only set
4926 /// `for_child_nodes_also` true if the participant can really promise to
4927 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
4928 /// weak VMO handles held by participants holding the corresponding child
4929 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
4930 /// which are using sysmem(1) can be weak, despite the clients of those
4931 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
4932 /// direct way to find out about `close_weak_asap`. This only applies to
4933 /// descendents of this `Node` which are using sysmem(1), not to this
4934 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
4935 /// token, which will fail allocation unless an ancestor of this `Node`
4936 /// specified `for_child_nodes_also` true.
4937 SetWeakOk { payload: NodeSetWeakOkRequest, control_handle: BufferCollectionControlHandle },
4938 /// The server_end will be closed after this `Node` and any child nodes have
4939 /// have released their buffer counts, making those counts available for
4940 /// reservation by a different `Node` via
4941 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
4942 ///
4943 /// The `Node` buffer counts may not be released until the entire tree of
4944 /// `Node`(s) is closed or failed, because
4945 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
4946 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
4947 /// `Node` buffer counts remain reserved until the orphaned node is later
4948 /// cleaned up.
4949 ///
4950 /// If the `Node` exceeds a fairly large number of attached eventpair server
4951 /// ends, a log message will indicate this and the `Node` (and the
4952 /// appropriate) sub-tree will fail.
4953 ///
4954 /// The `server_end` will remain open when
4955 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
4956 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
4957 /// [`fuchsia.sysmem2/BufferCollection`].
4958 ///
4959 /// This message can also be used with a
4960 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
4961 AttachNodeTracking {
4962 payload: NodeAttachNodeTrackingRequest,
4963 control_handle: BufferCollectionControlHandle,
4964 },
4965 /// Provide [`fuchsia.sysmem2/BufferCollectionConstraints`] to the buffer
4966 /// collection.
4967 ///
4968 /// A participant may only call
4969 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] up to once per
4970 /// [`fuchsia.sysmem2/BufferCollection`].
4971 ///
4972 /// For buffer allocation to be attempted, all holders of a
4973 /// `BufferCollection` client end need to call `SetConstraints` before
4974 /// sysmem will attempt to allocate buffers.
4975 SetConstraints {
4976 payload: BufferCollectionSetConstraintsRequest,
4977 control_handle: BufferCollectionControlHandle,
4978 },
4979 /// Wait until all buffers are allocated.
4980 ///
4981 /// This FIDL call completes when buffers have been allocated, or completes
4982 /// with some failure detail if allocation has been attempted but failed.
4983 ///
4984 /// The following must occur before buffers will be allocated:
4985 /// * All [`fuchsia.sysmem2/BufferCollectionToken`](s) of the buffer
4986 /// collection must be turned in via `BindSharedCollection` to get a
4987 /// [`fuchsia.sysmem2/BufferCollection`] (for brevity, this is assuming
4988 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`] isn't being used),
4989 /// or have had [`fuchsia.sysmem2/BufferCollectionToken.Release`] sent
4990 /// to them.
4991 /// * All [`fuchsia.sysmem2/BufferCollection`](s) of the buffer collection
4992 /// must have had [`fuchsia.sysmem2/BufferCollection.SetConstraints`]
4993 /// sent to them, or had [`fuchsia.sysmem2/BufferCollection.Release`]
4994 /// sent to them.
4995 ///
4996 /// - result `buffer_collection_info` The VMO handles and other related
4997 /// info.
4998 /// * error `[fuchsia.sysmem2/Error.NO_MEMORY]` The request is valid but
4999 /// cannot be fulfilled due to resource exhaustion.
5000 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION`] The request is
5001 /// malformed.
5002 /// * error `[fuchsia.sysmem2/Error.CONSTRAINTS_INTERSECTION_EMPTY`] The
5003 /// request is valid but cannot be satisfied, perhaps due to hardware
5004 /// limitations. This can happen if participants have incompatible
5005 /// constraints (empty intersection, roughly speaking). See the log for
5006 /// more info. In cases where a participant could potentially be treated
5007 /// as optional, see [`BufferCollectionTokenGroup`]. When using
5008 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], this will be the
5009 /// error code if there aren't enough buffers in the pre-existing
5010 /// collection to satisfy the constraints set on the attached token and
5011 /// any sub-tree of tokens derived from the attached token.
5012 WaitForAllBuffersAllocated { responder: BufferCollectionWaitForAllBuffersAllocatedResponder },
5013 /// Checks whether all the buffers have been allocated, in a polling
5014 /// fashion.
5015 ///
5016 /// * If the buffer collection has been allocated, returns success.
5017 /// * If the buffer collection failed allocation, returns the same
5018 /// [`fuchsia.sysmem2/Error`] as
5019 /// [`fuchsia.sysmem2/BufferCollection/WaitForAllBuffersAllocated`] would
5020 /// return.
5021 /// * error [`fuchsia.sysmem2/Error.PENDING`] The buffer collection hasn't
5022 /// attempted allocation yet. This means that WaitForAllBuffersAllocated
5023 /// would not respond quickly.
5024 CheckAllBuffersAllocated { responder: BufferCollectionCheckAllBuffersAllocatedResponder },
5025 /// Create a new token to add a new participant to an existing logical
5026 /// buffer collection, if the existing collection's buffer counts,
5027 /// constraints, and participants allow.
5028 ///
5029 /// This can be useful in replacing a failed participant, and/or in
5030 /// adding/re-adding a participant after buffers have already been
5031 /// allocated.
5032 ///
5033 /// When [`fuchsia.sysmem2/BufferCollection.AttachToken`] is used, the sub
5034 /// tree rooted at the attached [`fuchsia.sysmem2/BufferCollectionToken`]
5035 /// goes through the normal procedure of setting constraints or closing
5036 /// [`fuchsia.sysmem2/Node`](s), and then appearing to allocate buffers from
5037 /// clients' point of view, despite the possibility that all the buffers
5038 /// were actually allocated previously. This process is called "logical
5039 /// allocation". Most instances of "allocation" in docs for other messages
5040 /// can also be read as "allocation or logical allocation" while remaining
5041 /// valid, but we just say "allocation" in most places for brevity/clarity
5042 /// of explanation, with the details of "logical allocation" left for the
5043 /// docs here on `AttachToken`.
5044 ///
5045 /// Failure of an attached `Node` does not propagate to the parent of the
5046 /// attached `Node`. More generally, failure of a child `Node` is blocked
5047 /// from reaching its parent `Node` if the child is attached, or if the
5048 /// child is dispensable and the failure occurred after logical allocation
5049 /// (see [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`]).
5050 ///
5051 /// A participant may in some scenarios choose to initially use a
5052 /// dispensable token for a given instance of a delegate participant, and
5053 /// then later if the first instance of that delegate participant fails, a
5054 /// new second instance of that delegate participant my be given a token
5055 /// created with `AttachToken`.
5056 ///
5057 /// From the point of view of the [`fuchsia.sysmem2/BufferCollectionToken`]
5058 /// client end, the token acts like any other token. The client can
5059 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] the token as needed,
5060 /// and can send the token to a different process/participant. The
5061 /// `BufferCollectionToken` `Node` should be converted to a
5062 /// `BufferCollection` `Node` as normal by sending
5063 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or can be closed
5064 /// without causing subtree failure by sending
5065 /// [`fuchsia.sysmem2/BufferCollectionToken.Release`]. Assuming the former,
5066 /// the [`fuchsia.sysmem2/BufferCollection.SetConstraints`] message or
5067 /// [`fuchsia.sysmem2/BufferCollection.Release`] message should be sent to
5068 /// the `BufferCollection`.
5069 ///
5070 /// Within the subtree, a success result from
5071 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`] means
5072 /// the subtree participants' constraints were satisfiable using the
5073 /// already-existing buffer collection, the already-established
5074 /// [`fuchsia.sysmem2/BufferCollectionInfo`] including image format
5075 /// constraints, and the already-existing other participants (already added
5076 /// via successful logical allocation) and their specified buffer counts in
5077 /// their constraints. A failure result means the new participants'
5078 /// constraints cannot be satisfied using the existing buffer collection and
5079 /// its already-added participants. Creating a new collection instead may
5080 /// allow all participants' constraints to be satisfied, assuming
5081 /// `SetDispensable` is used in place of `AttachToken`, or a normal token is
5082 /// used.
5083 ///
5084 /// A token created with `AttachToken` performs constraints aggregation with
5085 /// all constraints currently in effect on the buffer collection, plus the
5086 /// attached token under consideration plus child tokens under the attached
5087 /// token which are not themselves an attached token or under such a token.
5088 /// Further subtrees under this subtree are considered for logical
5089 /// allocation only after this subtree has completed logical allocation.
5090 ///
5091 /// Assignment of existing buffers to participants'
5092 /// [`fuchsia.sysmem2/BufferCollectionConstraints.min_buffer_count_for_camping`]
5093 /// etc is first-come first-served, but a child can't logically allocate
5094 /// before all its parents have sent `SetConstraints`.
5095 ///
5096 /// See also [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`], which
5097 /// in contrast to `AttachToken`, has the created token `Node` + child
5098 /// `Node`(s) (in the created subtree but not in any subtree under this
5099 /// subtree) participate in constraints aggregation along with its parent
5100 /// during the parent's allocation or logical allocation.
5101 ///
5102 /// Similar to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], the
5103 /// newly created token needs to be [`fuchsia.sysmem2/Node.Sync`]ed to
5104 /// sysmem before the new token can be passed to `BindSharedCollection`. The
5105 /// `Sync` of the new token can be accomplished with
5106 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after converting the created
5107 /// `BufferCollectionToken` to a `BufferCollection`. Alternately,
5108 /// [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on the new token also
5109 /// works. Or using [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`]
5110 /// works. As usual, a `BufferCollectionToken.Sync` can be started after any
5111 /// `BufferCollectionToken.Duplicate` messages have been sent via the newly
5112 /// created token, to also sync those additional tokens to sysmem using a
5113 /// single round-trip.
5114 ///
5115 /// All table fields are currently required.
5116 ///
5117 /// + request `rights_attentuation_mask` This allows attenuating the VMO
5118 /// rights of the subtree. These values for `rights_attenuation_mask`
5119 /// result in no attenuation (note that 0 is not on this list):
5120 /// + ZX_RIGHT_SAME_RIGHTS (preferred)
5121 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
5122 /// + request `token_request` The server end of the `BufferCollectionToken`
5123 /// channel. The client retains the client end.
5124 AttachToken {
5125 payload: BufferCollectionAttachTokenRequest,
5126 control_handle: BufferCollectionControlHandle,
5127 },
5128 /// Set up an eventpair to be signalled (`ZX_EVENTPAIR_PEER_CLOSED`) when
5129 /// buffers have been allocated and only the specified number of buffers (or
5130 /// fewer) remain in the buffer collection.
5131 ///
5132 /// [`fuchsia.sysmem2/BufferCollection.AttachLifetimeTracking`] allows a
5133 /// client to wait until an old buffer collection is fully or mostly
5134 /// deallocated before attempting allocation of a new buffer collection. The
5135 /// eventpair is only signalled when the buffers of this collection have
5136 /// been fully deallocated (not just un-referenced by clients, but all the
5137 /// memory consumed by those buffers has been fully reclaimed/recycled), or
5138 /// when allocation or logical allocation fails for the tree or subtree
5139 /// including this [`fuchsia.sysmem2/BufferCollection`].
5140 ///
5141 /// The eventpair won't be signalled until allocation or logical allocation
5142 /// has completed; until then, the collection's current buffer count is
5143 /// ignored.
5144 ///
5145 /// If logical allocation fails for an attached subtree (using
5146 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]), the server end of the
5147 /// eventpair will close during that failure regardless of the number of
5148 /// buffers potenitally allocated in the overall buffer collection. This is
5149 /// for logical allocation consistency with normal allocation.
5150 ///
5151 /// The lifetime signalled by this event includes asynchronous cleanup of
5152 /// allocated buffers, and this asynchronous cleanup cannot occur until all
5153 /// holders of VMO handles to the buffers have closed those VMO handles.
5154 /// Therefore, clients should take care not to become blocked forever
5155 /// waiting for `ZX_EVENTPAIR_PEER_CLOSED` to be signalled if any of the
5156 /// participants using the logical buffer collection (including the waiter
5157 /// itself) are less trusted, less reliable, or potentially blocked by the
5158 /// wait itself. Waiting asynchronously is recommended. Setting a deadline
5159 /// for the client wait may be prudent, depending on details of how the
5160 /// collection and/or its VMOs are used or shared. Failure to allocate a
5161 /// new/replacement buffer collection is better than getting stuck forever.
5162 ///
5163 /// The sysmem server itself intentionally does not perform any waiting on
5164 /// already-failed collections' VMOs to finish cleaning up before attempting
5165 /// a new allocation, and the sysmem server intentionally doesn't retry
5166 /// allocation if a new allocation fails due to out of memory, even if that
5167 /// failure is potentially due to continued existence of an old collection's
5168 /// VMOs. This `AttachLifetimeTracking` message is how an initiator can
5169 /// mitigate too much overlap of old VMO lifetimes with new VMO lifetimes,
5170 /// as long as the waiting client is careful to not create a deadlock.
5171 ///
5172 /// Continued existence of old collections that are still cleaning up is not
5173 /// the only reason that a new allocation may fail due to insufficient
5174 /// memory, even if the new allocation is allocating physically contiguous
5175 /// buffers. Overall system memory pressure can also be the cause of failure
5176 /// to allocate a new collection. See also
5177 /// [`fuchsia.memorypressure/Provider`].
5178 ///
5179 /// `AttachLifetimeTracking` is meant to be compatible with other protocols
5180 /// with a similar `AttachLifetimeTracking` message; duplicates of the same
5181 /// `eventpair` handle (server end) can be sent via more than one
5182 /// `AttachLifetimeTracking` message to different protocols, and the
5183 /// `ZX_EVENTPAIR_PEER_CLOSED` will be signalled for the client end when all
5184 /// the conditions are met (all holders of duplicates have closed their
5185 /// server end handle(s)). Also, thanks to how eventpair endponts work, the
5186 /// client end can (also) be duplicated without preventing the
5187 /// `ZX_EVENTPAIR_PEER_CLOSED` signal.
5188 ///
5189 /// The server intentionally doesn't "trust" any signals set on the
5190 /// `server_end`. This mechanism intentionally uses only
5191 /// `ZX_EVENTPAIR_PEER_CLOSED` set on the client end, which can't be set
5192 /// "early", and is only set when all handles to the server end eventpair
5193 /// are closed. No meaning is associated with any of the other signals, and
5194 /// clients should ignore any other signal bits on either end of the
5195 /// `eventpair`.
5196 ///
5197 /// The `server_end` may lack `ZX_RIGHT_SIGNAL` or `ZX_RIGHT_SIGNAL_PEER`,
5198 /// but must have `ZX_RIGHT_DUPLICATE` (and must have `ZX_RIGHT_TRANSFER` to
5199 /// transfer without causing `BufferCollection` channel failure).
5200 ///
5201 /// All table fields are currently required.
5202 ///
5203 /// + request `server_end` This eventpair handle will be closed by the
5204 /// sysmem server when buffers have been allocated initially and the
5205 /// number of buffers is then less than or equal to `buffers_remaining`.
5206 /// + request `buffers_remaining` Wait for all but `buffers_remaining` (or
5207 /// fewer) buffers to be fully deallocated. A number greater than zero can
5208 /// be useful in situations where a known number of buffers are
5209 /// intentionally not closed so that the data can continue to be used,
5210 /// such as for keeping the last available video frame displayed in the UI
5211 /// even if the video stream was using protected output buffers. It's
5212 /// outside the scope of the `BufferCollection` interface (at least for
5213 /// now) to determine how many buffers may be held without closing, but
5214 /// it'll typically be in the range 0-2.
5215 AttachLifetimeTracking {
5216 payload: BufferCollectionAttachLifetimeTrackingRequest,
5217 control_handle: BufferCollectionControlHandle,
5218 },
5219 /// An interaction was received which does not match any known method.
5220 #[non_exhaustive]
5221 _UnknownMethod {
5222 /// Ordinal of the method that was called.
5223 ordinal: u64,
5224 control_handle: BufferCollectionControlHandle,
5225 method_type: fidl::MethodType,
5226 },
5227}
5228
5229impl BufferCollectionRequest {
5230 #[allow(irrefutable_let_patterns)]
5231 pub fn into_sync(self) -> Option<(BufferCollectionSyncResponder)> {
5232 if let BufferCollectionRequest::Sync { responder } = self {
5233 Some((responder))
5234 } else {
5235 None
5236 }
5237 }
5238
5239 #[allow(irrefutable_let_patterns)]
5240 pub fn into_release(self) -> Option<(BufferCollectionControlHandle)> {
5241 if let BufferCollectionRequest::Release { control_handle } = self {
5242 Some((control_handle))
5243 } else {
5244 None
5245 }
5246 }
5247
5248 #[allow(irrefutable_let_patterns)]
5249 pub fn into_set_name(self) -> Option<(NodeSetNameRequest, BufferCollectionControlHandle)> {
5250 if let BufferCollectionRequest::SetName { payload, control_handle } = self {
5251 Some((payload, control_handle))
5252 } else {
5253 None
5254 }
5255 }
5256
5257 #[allow(irrefutable_let_patterns)]
5258 pub fn into_set_debug_client_info(
5259 self,
5260 ) -> Option<(NodeSetDebugClientInfoRequest, BufferCollectionControlHandle)> {
5261 if let BufferCollectionRequest::SetDebugClientInfo { payload, control_handle } = self {
5262 Some((payload, control_handle))
5263 } else {
5264 None
5265 }
5266 }
5267
5268 #[allow(irrefutable_let_patterns)]
5269 pub fn into_set_debug_timeout_log_deadline(
5270 self,
5271 ) -> Option<(NodeSetDebugTimeoutLogDeadlineRequest, BufferCollectionControlHandle)> {
5272 if let BufferCollectionRequest::SetDebugTimeoutLogDeadline { payload, control_handle } =
5273 self
5274 {
5275 Some((payload, control_handle))
5276 } else {
5277 None
5278 }
5279 }
5280
5281 #[allow(irrefutable_let_patterns)]
5282 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionControlHandle)> {
5283 if let BufferCollectionRequest::SetVerboseLogging { control_handle } = self {
5284 Some((control_handle))
5285 } else {
5286 None
5287 }
5288 }
5289
5290 #[allow(irrefutable_let_patterns)]
5291 pub fn into_get_node_ref(self) -> Option<(BufferCollectionGetNodeRefResponder)> {
5292 if let BufferCollectionRequest::GetNodeRef { responder } = self {
5293 Some((responder))
5294 } else {
5295 None
5296 }
5297 }
5298
5299 #[allow(irrefutable_let_patterns)]
5300 pub fn into_is_alternate_for(
5301 self,
5302 ) -> Option<(NodeIsAlternateForRequest, BufferCollectionIsAlternateForResponder)> {
5303 if let BufferCollectionRequest::IsAlternateFor { payload, responder } = self {
5304 Some((payload, responder))
5305 } else {
5306 None
5307 }
5308 }
5309
5310 #[allow(irrefutable_let_patterns)]
5311 pub fn into_get_buffer_collection_id(
5312 self,
5313 ) -> Option<(BufferCollectionGetBufferCollectionIdResponder)> {
5314 if let BufferCollectionRequest::GetBufferCollectionId { responder } = self {
5315 Some((responder))
5316 } else {
5317 None
5318 }
5319 }
5320
5321 #[allow(irrefutable_let_patterns)]
5322 pub fn into_set_weak(self) -> Option<(BufferCollectionControlHandle)> {
5323 if let BufferCollectionRequest::SetWeak { control_handle } = self {
5324 Some((control_handle))
5325 } else {
5326 None
5327 }
5328 }
5329
5330 #[allow(irrefutable_let_patterns)]
5331 pub fn into_set_weak_ok(self) -> Option<(NodeSetWeakOkRequest, BufferCollectionControlHandle)> {
5332 if let BufferCollectionRequest::SetWeakOk { payload, control_handle } = self {
5333 Some((payload, control_handle))
5334 } else {
5335 None
5336 }
5337 }
5338
5339 #[allow(irrefutable_let_patterns)]
5340 pub fn into_attach_node_tracking(
5341 self,
5342 ) -> Option<(NodeAttachNodeTrackingRequest, BufferCollectionControlHandle)> {
5343 if let BufferCollectionRequest::AttachNodeTracking { payload, control_handle } = self {
5344 Some((payload, control_handle))
5345 } else {
5346 None
5347 }
5348 }
5349
5350 #[allow(irrefutable_let_patterns)]
5351 pub fn into_set_constraints(
5352 self,
5353 ) -> Option<(BufferCollectionSetConstraintsRequest, BufferCollectionControlHandle)> {
5354 if let BufferCollectionRequest::SetConstraints { payload, control_handle } = self {
5355 Some((payload, control_handle))
5356 } else {
5357 None
5358 }
5359 }
5360
5361 #[allow(irrefutable_let_patterns)]
5362 pub fn into_wait_for_all_buffers_allocated(
5363 self,
5364 ) -> Option<(BufferCollectionWaitForAllBuffersAllocatedResponder)> {
5365 if let BufferCollectionRequest::WaitForAllBuffersAllocated { responder } = self {
5366 Some((responder))
5367 } else {
5368 None
5369 }
5370 }
5371
5372 #[allow(irrefutable_let_patterns)]
5373 pub fn into_check_all_buffers_allocated(
5374 self,
5375 ) -> Option<(BufferCollectionCheckAllBuffersAllocatedResponder)> {
5376 if let BufferCollectionRequest::CheckAllBuffersAllocated { responder } = self {
5377 Some((responder))
5378 } else {
5379 None
5380 }
5381 }
5382
5383 #[allow(irrefutable_let_patterns)]
5384 pub fn into_attach_token(
5385 self,
5386 ) -> Option<(BufferCollectionAttachTokenRequest, BufferCollectionControlHandle)> {
5387 if let BufferCollectionRequest::AttachToken { payload, control_handle } = self {
5388 Some((payload, control_handle))
5389 } else {
5390 None
5391 }
5392 }
5393
5394 #[allow(irrefutable_let_patterns)]
5395 pub fn into_attach_lifetime_tracking(
5396 self,
5397 ) -> Option<(BufferCollectionAttachLifetimeTrackingRequest, BufferCollectionControlHandle)>
5398 {
5399 if let BufferCollectionRequest::AttachLifetimeTracking { payload, control_handle } = self {
5400 Some((payload, control_handle))
5401 } else {
5402 None
5403 }
5404 }
5405
5406 /// Name of the method defined in FIDL
5407 pub fn method_name(&self) -> &'static str {
5408 match *self {
5409 BufferCollectionRequest::Sync { .. } => "sync",
5410 BufferCollectionRequest::Release { .. } => "release",
5411 BufferCollectionRequest::SetName { .. } => "set_name",
5412 BufferCollectionRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
5413 BufferCollectionRequest::SetDebugTimeoutLogDeadline { .. } => {
5414 "set_debug_timeout_log_deadline"
5415 }
5416 BufferCollectionRequest::SetVerboseLogging { .. } => "set_verbose_logging",
5417 BufferCollectionRequest::GetNodeRef { .. } => "get_node_ref",
5418 BufferCollectionRequest::IsAlternateFor { .. } => "is_alternate_for",
5419 BufferCollectionRequest::GetBufferCollectionId { .. } => "get_buffer_collection_id",
5420 BufferCollectionRequest::SetWeak { .. } => "set_weak",
5421 BufferCollectionRequest::SetWeakOk { .. } => "set_weak_ok",
5422 BufferCollectionRequest::AttachNodeTracking { .. } => "attach_node_tracking",
5423 BufferCollectionRequest::SetConstraints { .. } => "set_constraints",
5424 BufferCollectionRequest::WaitForAllBuffersAllocated { .. } => {
5425 "wait_for_all_buffers_allocated"
5426 }
5427 BufferCollectionRequest::CheckAllBuffersAllocated { .. } => {
5428 "check_all_buffers_allocated"
5429 }
5430 BufferCollectionRequest::AttachToken { .. } => "attach_token",
5431 BufferCollectionRequest::AttachLifetimeTracking { .. } => "attach_lifetime_tracking",
5432 BufferCollectionRequest::_UnknownMethod {
5433 method_type: fidl::MethodType::OneWay,
5434 ..
5435 } => "unknown one-way method",
5436 BufferCollectionRequest::_UnknownMethod {
5437 method_type: fidl::MethodType::TwoWay,
5438 ..
5439 } => "unknown two-way method",
5440 }
5441 }
5442}
5443
5444#[derive(Debug, Clone)]
5445pub struct BufferCollectionControlHandle {
5446 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
5447}
5448
5449impl fidl::endpoints::ControlHandle for BufferCollectionControlHandle {
5450 fn shutdown(&self) {
5451 self.inner.shutdown()
5452 }
5453
5454 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
5455 self.inner.shutdown_with_epitaph(status)
5456 }
5457
5458 fn is_closed(&self) -> bool {
5459 self.inner.channel().is_closed()
5460 }
5461 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
5462 self.inner.channel().on_closed()
5463 }
5464
5465 #[cfg(target_os = "fuchsia")]
5466 fn signal_peer(
5467 &self,
5468 clear_mask: zx::Signals,
5469 set_mask: zx::Signals,
5470 ) -> Result<(), zx_status::Status> {
5471 use fidl::Peered;
5472 self.inner.channel().signal_peer(clear_mask, set_mask)
5473 }
5474}
5475
5476impl BufferCollectionControlHandle {}
5477
5478#[must_use = "FIDL methods require a response to be sent"]
5479#[derive(Debug)]
5480pub struct BufferCollectionSyncResponder {
5481 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5482 tx_id: u32,
5483}
5484
5485/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5486/// if the responder is dropped without sending a response, so that the client
5487/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5488impl std::ops::Drop for BufferCollectionSyncResponder {
5489 fn drop(&mut self) {
5490 self.control_handle.shutdown();
5491 // Safety: drops once, never accessed again
5492 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5493 }
5494}
5495
5496impl fidl::endpoints::Responder for BufferCollectionSyncResponder {
5497 type ControlHandle = BufferCollectionControlHandle;
5498
5499 fn control_handle(&self) -> &BufferCollectionControlHandle {
5500 &self.control_handle
5501 }
5502
5503 fn drop_without_shutdown(mut self) {
5504 // Safety: drops once, never accessed again due to mem::forget
5505 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5506 // Prevent Drop from running (which would shut down the channel)
5507 std::mem::forget(self);
5508 }
5509}
5510
5511impl BufferCollectionSyncResponder {
5512 /// Sends a response to the FIDL transaction.
5513 ///
5514 /// Sets the channel to shutdown if an error occurs.
5515 pub fn send(self) -> Result<(), fidl::Error> {
5516 let _result = self.send_raw();
5517 if _result.is_err() {
5518 self.control_handle.shutdown();
5519 }
5520 self.drop_without_shutdown();
5521 _result
5522 }
5523
5524 /// Similar to "send" but does not shutdown the channel if an error occurs.
5525 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
5526 let _result = self.send_raw();
5527 self.drop_without_shutdown();
5528 _result
5529 }
5530
5531 fn send_raw(&self) -> Result<(), fidl::Error> {
5532 self.control_handle.inner.send::<fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>>(
5533 fidl::encoding::Flexible::new(()),
5534 self.tx_id,
5535 0x11ac2555cf575b54,
5536 fidl::encoding::DynamicFlags::FLEXIBLE,
5537 )
5538 }
5539}
5540
5541#[must_use = "FIDL methods require a response to be sent"]
5542#[derive(Debug)]
5543pub struct BufferCollectionGetNodeRefResponder {
5544 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5545 tx_id: u32,
5546}
5547
5548/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5549/// if the responder is dropped without sending a response, so that the client
5550/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5551impl std::ops::Drop for BufferCollectionGetNodeRefResponder {
5552 fn drop(&mut self) {
5553 self.control_handle.shutdown();
5554 // Safety: drops once, never accessed again
5555 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5556 }
5557}
5558
5559impl fidl::endpoints::Responder for BufferCollectionGetNodeRefResponder {
5560 type ControlHandle = BufferCollectionControlHandle;
5561
5562 fn control_handle(&self) -> &BufferCollectionControlHandle {
5563 &self.control_handle
5564 }
5565
5566 fn drop_without_shutdown(mut self) {
5567 // Safety: drops once, never accessed again due to mem::forget
5568 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5569 // Prevent Drop from running (which would shut down the channel)
5570 std::mem::forget(self);
5571 }
5572}
5573
5574impl BufferCollectionGetNodeRefResponder {
5575 /// Sends a response to the FIDL transaction.
5576 ///
5577 /// Sets the channel to shutdown if an error occurs.
5578 pub fn send(self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
5579 let _result = self.send_raw(payload);
5580 if _result.is_err() {
5581 self.control_handle.shutdown();
5582 }
5583 self.drop_without_shutdown();
5584 _result
5585 }
5586
5587 /// Similar to "send" but does not shutdown the channel if an error occurs.
5588 pub fn send_no_shutdown_on_err(
5589 self,
5590 mut payload: NodeGetNodeRefResponse,
5591 ) -> Result<(), fidl::Error> {
5592 let _result = self.send_raw(payload);
5593 self.drop_without_shutdown();
5594 _result
5595 }
5596
5597 fn send_raw(&self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
5598 self.control_handle.inner.send::<fidl::encoding::FlexibleType<NodeGetNodeRefResponse>>(
5599 fidl::encoding::Flexible::new(&mut payload),
5600 self.tx_id,
5601 0x5b3d0e51614df053,
5602 fidl::encoding::DynamicFlags::FLEXIBLE,
5603 )
5604 }
5605}
5606
5607#[must_use = "FIDL methods require a response to be sent"]
5608#[derive(Debug)]
5609pub struct BufferCollectionIsAlternateForResponder {
5610 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5611 tx_id: u32,
5612}
5613
5614/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5615/// if the responder is dropped without sending a response, so that the client
5616/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5617impl std::ops::Drop for BufferCollectionIsAlternateForResponder {
5618 fn drop(&mut self) {
5619 self.control_handle.shutdown();
5620 // Safety: drops once, never accessed again
5621 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5622 }
5623}
5624
5625impl fidl::endpoints::Responder for BufferCollectionIsAlternateForResponder {
5626 type ControlHandle = BufferCollectionControlHandle;
5627
5628 fn control_handle(&self) -> &BufferCollectionControlHandle {
5629 &self.control_handle
5630 }
5631
5632 fn drop_without_shutdown(mut self) {
5633 // Safety: drops once, never accessed again due to mem::forget
5634 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5635 // Prevent Drop from running (which would shut down the channel)
5636 std::mem::forget(self);
5637 }
5638}
5639
5640impl BufferCollectionIsAlternateForResponder {
5641 /// Sends a response to the FIDL transaction.
5642 ///
5643 /// Sets the channel to shutdown if an error occurs.
5644 pub fn send(
5645 self,
5646 mut result: Result<&NodeIsAlternateForResponse, Error>,
5647 ) -> Result<(), fidl::Error> {
5648 let _result = self.send_raw(result);
5649 if _result.is_err() {
5650 self.control_handle.shutdown();
5651 }
5652 self.drop_without_shutdown();
5653 _result
5654 }
5655
5656 /// Similar to "send" but does not shutdown the channel if an error occurs.
5657 pub fn send_no_shutdown_on_err(
5658 self,
5659 mut result: Result<&NodeIsAlternateForResponse, Error>,
5660 ) -> Result<(), fidl::Error> {
5661 let _result = self.send_raw(result);
5662 self.drop_without_shutdown();
5663 _result
5664 }
5665
5666 fn send_raw(
5667 &self,
5668 mut result: Result<&NodeIsAlternateForResponse, Error>,
5669 ) -> Result<(), fidl::Error> {
5670 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
5671 NodeIsAlternateForResponse,
5672 Error,
5673 >>(
5674 fidl::encoding::FlexibleResult::new(result),
5675 self.tx_id,
5676 0x3a58e00157e0825,
5677 fidl::encoding::DynamicFlags::FLEXIBLE,
5678 )
5679 }
5680}
5681
5682#[must_use = "FIDL methods require a response to be sent"]
5683#[derive(Debug)]
5684pub struct BufferCollectionGetBufferCollectionIdResponder {
5685 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5686 tx_id: u32,
5687}
5688
5689/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5690/// if the responder is dropped without sending a response, so that the client
5691/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5692impl std::ops::Drop for BufferCollectionGetBufferCollectionIdResponder {
5693 fn drop(&mut self) {
5694 self.control_handle.shutdown();
5695 // Safety: drops once, never accessed again
5696 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5697 }
5698}
5699
5700impl fidl::endpoints::Responder for BufferCollectionGetBufferCollectionIdResponder {
5701 type ControlHandle = BufferCollectionControlHandle;
5702
5703 fn control_handle(&self) -> &BufferCollectionControlHandle {
5704 &self.control_handle
5705 }
5706
5707 fn drop_without_shutdown(mut self) {
5708 // Safety: drops once, never accessed again due to mem::forget
5709 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5710 // Prevent Drop from running (which would shut down the channel)
5711 std::mem::forget(self);
5712 }
5713}
5714
5715impl BufferCollectionGetBufferCollectionIdResponder {
5716 /// Sends a response to the FIDL transaction.
5717 ///
5718 /// Sets the channel to shutdown if an error occurs.
5719 pub fn send(self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
5720 let _result = self.send_raw(payload);
5721 if _result.is_err() {
5722 self.control_handle.shutdown();
5723 }
5724 self.drop_without_shutdown();
5725 _result
5726 }
5727
5728 /// Similar to "send" but does not shutdown the channel if an error occurs.
5729 pub fn send_no_shutdown_on_err(
5730 self,
5731 mut payload: &NodeGetBufferCollectionIdResponse,
5732 ) -> Result<(), fidl::Error> {
5733 let _result = self.send_raw(payload);
5734 self.drop_without_shutdown();
5735 _result
5736 }
5737
5738 fn send_raw(&self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
5739 self.control_handle
5740 .inner
5741 .send::<fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>>(
5742 fidl::encoding::Flexible::new(payload),
5743 self.tx_id,
5744 0x77d19a494b78ba8c,
5745 fidl::encoding::DynamicFlags::FLEXIBLE,
5746 )
5747 }
5748}
5749
5750#[must_use = "FIDL methods require a response to be sent"]
5751#[derive(Debug)]
5752pub struct BufferCollectionWaitForAllBuffersAllocatedResponder {
5753 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5754 tx_id: u32,
5755}
5756
5757/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5758/// if the responder is dropped without sending a response, so that the client
5759/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5760impl std::ops::Drop for BufferCollectionWaitForAllBuffersAllocatedResponder {
5761 fn drop(&mut self) {
5762 self.control_handle.shutdown();
5763 // Safety: drops once, never accessed again
5764 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5765 }
5766}
5767
5768impl fidl::endpoints::Responder for BufferCollectionWaitForAllBuffersAllocatedResponder {
5769 type ControlHandle = BufferCollectionControlHandle;
5770
5771 fn control_handle(&self) -> &BufferCollectionControlHandle {
5772 &self.control_handle
5773 }
5774
5775 fn drop_without_shutdown(mut self) {
5776 // Safety: drops once, never accessed again due to mem::forget
5777 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5778 // Prevent Drop from running (which would shut down the channel)
5779 std::mem::forget(self);
5780 }
5781}
5782
5783impl BufferCollectionWaitForAllBuffersAllocatedResponder {
5784 /// Sends a response to the FIDL transaction.
5785 ///
5786 /// Sets the channel to shutdown if an error occurs.
5787 pub fn send(
5788 self,
5789 mut result: Result<BufferCollectionWaitForAllBuffersAllocatedResponse, Error>,
5790 ) -> Result<(), fidl::Error> {
5791 let _result = self.send_raw(result);
5792 if _result.is_err() {
5793 self.control_handle.shutdown();
5794 }
5795 self.drop_without_shutdown();
5796 _result
5797 }
5798
5799 /// Similar to "send" but does not shutdown the channel if an error occurs.
5800 pub fn send_no_shutdown_on_err(
5801 self,
5802 mut result: Result<BufferCollectionWaitForAllBuffersAllocatedResponse, Error>,
5803 ) -> Result<(), fidl::Error> {
5804 let _result = self.send_raw(result);
5805 self.drop_without_shutdown();
5806 _result
5807 }
5808
5809 fn send_raw(
5810 &self,
5811 mut result: Result<BufferCollectionWaitForAllBuffersAllocatedResponse, Error>,
5812 ) -> Result<(), fidl::Error> {
5813 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
5814 BufferCollectionWaitForAllBuffersAllocatedResponse,
5815 Error,
5816 >>(
5817 fidl::encoding::FlexibleResult::new(result.as_mut().map_err(|e| *e)),
5818 self.tx_id,
5819 0x62300344b61404e,
5820 fidl::encoding::DynamicFlags::FLEXIBLE,
5821 )
5822 }
5823}
5824
5825#[must_use = "FIDL methods require a response to be sent"]
5826#[derive(Debug)]
5827pub struct BufferCollectionCheckAllBuffersAllocatedResponder {
5828 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
5829 tx_id: u32,
5830}
5831
5832/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
5833/// if the responder is dropped without sending a response, so that the client
5834/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
5835impl std::ops::Drop for BufferCollectionCheckAllBuffersAllocatedResponder {
5836 fn drop(&mut self) {
5837 self.control_handle.shutdown();
5838 // Safety: drops once, never accessed again
5839 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5840 }
5841}
5842
5843impl fidl::endpoints::Responder for BufferCollectionCheckAllBuffersAllocatedResponder {
5844 type ControlHandle = BufferCollectionControlHandle;
5845
5846 fn control_handle(&self) -> &BufferCollectionControlHandle {
5847 &self.control_handle
5848 }
5849
5850 fn drop_without_shutdown(mut self) {
5851 // Safety: drops once, never accessed again due to mem::forget
5852 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
5853 // Prevent Drop from running (which would shut down the channel)
5854 std::mem::forget(self);
5855 }
5856}
5857
5858impl BufferCollectionCheckAllBuffersAllocatedResponder {
5859 /// Sends a response to the FIDL transaction.
5860 ///
5861 /// Sets the channel to shutdown if an error occurs.
5862 pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
5863 let _result = self.send_raw(result);
5864 if _result.is_err() {
5865 self.control_handle.shutdown();
5866 }
5867 self.drop_without_shutdown();
5868 _result
5869 }
5870
5871 /// Similar to "send" but does not shutdown the channel if an error occurs.
5872 pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
5873 let _result = self.send_raw(result);
5874 self.drop_without_shutdown();
5875 _result
5876 }
5877
5878 fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
5879 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
5880 fidl::encoding::EmptyStruct,
5881 Error,
5882 >>(
5883 fidl::encoding::FlexibleResult::new(result),
5884 self.tx_id,
5885 0x35a5fe77ce939c10,
5886 fidl::encoding::DynamicFlags::FLEXIBLE,
5887 )
5888 }
5889}
5890
5891#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
5892pub struct BufferCollectionTokenMarker;
5893
5894impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenMarker {
5895 type Proxy = BufferCollectionTokenProxy;
5896 type RequestStream = BufferCollectionTokenRequestStream;
5897 #[cfg(target_os = "fuchsia")]
5898 type SynchronousProxy = BufferCollectionTokenSynchronousProxy;
5899
5900 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionToken";
5901}
5902
5903pub trait BufferCollectionTokenProxyInterface: Send + Sync {
5904 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
5905 fn r#sync(&self) -> Self::SyncResponseFut;
5906 fn r#release(&self) -> Result<(), fidl::Error>;
5907 fn r#set_name(&self, payload: &NodeSetNameRequest) -> Result<(), fidl::Error>;
5908 fn r#set_debug_client_info(
5909 &self,
5910 payload: &NodeSetDebugClientInfoRequest,
5911 ) -> Result<(), fidl::Error>;
5912 fn r#set_debug_timeout_log_deadline(
5913 &self,
5914 payload: &NodeSetDebugTimeoutLogDeadlineRequest,
5915 ) -> Result<(), fidl::Error>;
5916 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
5917 type GetNodeRefResponseFut: std::future::Future<Output = Result<NodeGetNodeRefResponse, fidl::Error>>
5918 + Send;
5919 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
5920 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
5921 + Send;
5922 fn r#is_alternate_for(
5923 &self,
5924 payload: NodeIsAlternateForRequest,
5925 ) -> Self::IsAlternateForResponseFut;
5926 type GetBufferCollectionIdResponseFut: std::future::Future<Output = Result<NodeGetBufferCollectionIdResponse, fidl::Error>>
5927 + Send;
5928 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut;
5929 fn r#set_weak(&self) -> Result<(), fidl::Error>;
5930 fn r#set_weak_ok(&self, payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error>;
5931 fn r#attach_node_tracking(
5932 &self,
5933 payload: NodeAttachNodeTrackingRequest,
5934 ) -> Result<(), fidl::Error>;
5935 type DuplicateSyncResponseFut: std::future::Future<
5936 Output = Result<BufferCollectionTokenDuplicateSyncResponse, fidl::Error>,
5937 > + Send;
5938 fn r#duplicate_sync(
5939 &self,
5940 payload: &BufferCollectionTokenDuplicateSyncRequest,
5941 ) -> Self::DuplicateSyncResponseFut;
5942 fn r#duplicate(
5943 &self,
5944 payload: BufferCollectionTokenDuplicateRequest,
5945 ) -> Result<(), fidl::Error>;
5946 fn r#set_dispensable(&self) -> Result<(), fidl::Error>;
5947 fn r#create_buffer_collection_token_group(
5948 &self,
5949 payload: BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
5950 ) -> Result<(), fidl::Error>;
5951}
5952#[derive(Debug)]
5953#[cfg(target_os = "fuchsia")]
5954pub struct BufferCollectionTokenSynchronousProxy {
5955 client: fidl::client::sync::Client,
5956}
5957
5958#[cfg(target_os = "fuchsia")]
5959impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenSynchronousProxy {
5960 type Proxy = BufferCollectionTokenProxy;
5961 type Protocol = BufferCollectionTokenMarker;
5962
5963 fn from_channel(inner: fidl::Channel) -> Self {
5964 Self::new(inner)
5965 }
5966
5967 fn into_channel(self) -> fidl::Channel {
5968 self.client.into_channel()
5969 }
5970
5971 fn as_channel(&self) -> &fidl::Channel {
5972 self.client.as_channel()
5973 }
5974}
5975
5976#[cfg(target_os = "fuchsia")]
5977impl BufferCollectionTokenSynchronousProxy {
5978 pub fn new(channel: fidl::Channel) -> Self {
5979 Self { client: fidl::client::sync::Client::new(channel) }
5980 }
5981
5982 pub fn into_channel(self) -> fidl::Channel {
5983 self.client.into_channel()
5984 }
5985
5986 /// Waits until an event arrives and returns it. It is safe for other
5987 /// threads to make concurrent requests while waiting for an event.
5988 pub fn wait_for_event(
5989 &self,
5990 deadline: zx::MonotonicInstant,
5991 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
5992 BufferCollectionTokenEvent::decode(
5993 self.client.wait_for_event::<BufferCollectionTokenMarker>(deadline)?,
5994 )
5995 }
5996
5997 /// Ensure that previous messages have been received server side. This is
5998 /// particularly useful after previous messages that created new tokens,
5999 /// because a token must be known to the sysmem server before sending the
6000 /// token to another participant.
6001 ///
6002 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
6003 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
6004 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
6005 /// to mitigate the possibility of a hostile/fake
6006 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
6007 /// Another way is to pass the token to
6008 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
6009 /// the token as part of exchanging it for a
6010 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
6011 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
6012 /// of stalling.
6013 ///
6014 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
6015 /// and then starting and completing a `Sync`, it's then safe to send the
6016 /// `BufferCollectionToken` client ends to other participants knowing the
6017 /// server will recognize the tokens when they're sent by the other
6018 /// participants to sysmem in a
6019 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
6020 /// efficient way to create tokens while avoiding unnecessary round trips.
6021 ///
6022 /// Other options include waiting for each
6023 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
6024 /// individually (using separate call to `Sync` after each), or calling
6025 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
6026 /// converted to a `BufferCollection` via
6027 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
6028 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
6029 /// the sync step and can create multiple tokens at once.
6030 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
6031 let _response = self.client.send_query::<
6032 fidl::encoding::EmptyPayload,
6033 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
6034 BufferCollectionTokenMarker,
6035 >(
6036 (),
6037 0x11ac2555cf575b54,
6038 fidl::encoding::DynamicFlags::FLEXIBLE,
6039 ___deadline,
6040 )?
6041 .into_result::<BufferCollectionTokenMarker>("sync")?;
6042 Ok(_response)
6043 }
6044
6045 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
6046 ///
6047 /// Normally a participant will convert a `BufferCollectionToken` into a
6048 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
6049 /// `Release` via the token (and then close the channel immediately or
6050 /// shortly later in response to server closing the server end), which
6051 /// avoids causing buffer collection failure. Without a prior `Release`,
6052 /// closing the `BufferCollectionToken` client end will cause buffer
6053 /// collection failure.
6054 ///
6055 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
6056 ///
6057 /// By default the server handles unexpected closure of a
6058 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
6059 /// first) by failing the buffer collection. Partly this is to expedite
6060 /// closing VMO handles to reclaim memory when any participant fails. If a
6061 /// participant would like to cleanly close a `BufferCollection` without
6062 /// causing buffer collection failure, the participant can send `Release`
6063 /// before closing the `BufferCollection` client end. The `Release` can
6064 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
6065 /// buffer collection won't require constraints from this node in order to
6066 /// allocate. If after `SetConstraints`, the constraints are retained and
6067 /// aggregated, despite the lack of `BufferCollection` connection at the
6068 /// time of constraints aggregation.
6069 ///
6070 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
6071 ///
6072 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
6073 /// end (without `Release` first) will trigger failure of the buffer
6074 /// collection. To close a `BufferCollectionTokenGroup` channel without
6075 /// failing the buffer collection, ensure that AllChildrenPresent() has been
6076 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
6077 /// client end.
6078 ///
6079 /// If `Release` occurs before
6080 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
6081 /// buffer collection will fail (triggered by reception of `Release` without
6082 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
6083 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
6084 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
6085 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
6086 /// close requires `AllChildrenPresent` (if not already sent), then
6087 /// `Release`, then close client end.
6088 ///
6089 /// If `Release` occurs after `AllChildrenPresent`, the children and all
6090 /// their constraints remain intact (just as they would if the
6091 /// `BufferCollectionTokenGroup` channel had remained open), and the client
6092 /// end close doesn't trigger buffer collection failure.
6093 ///
6094 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
6095 ///
6096 /// For brevity, the per-channel-protocol paragraphs above ignore the
6097 /// separate failure domain created by
6098 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
6099 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
6100 /// unexpectedly closes (without `Release` first) and that client end is
6101 /// under a failure domain, instead of failing the whole buffer collection,
6102 /// the failure domain is failed, but the buffer collection itself is
6103 /// isolated from failure of the failure domain. Such failure domains can be
6104 /// nested, in which case only the inner-most failure domain in which the
6105 /// `Node` resides fails.
6106 pub fn r#release(&self) -> Result<(), fidl::Error> {
6107 self.client.send::<fidl::encoding::EmptyPayload>(
6108 (),
6109 0x6a5cae7d6d6e04c6,
6110 fidl::encoding::DynamicFlags::FLEXIBLE,
6111 )
6112 }
6113
6114 /// Set a name for VMOs in this buffer collection.
6115 ///
6116 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
6117 /// will be truncated to fit. The name of the vmo will be suffixed with the
6118 /// buffer index within the collection (if the suffix fits within
6119 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
6120 /// listed in the inspect data.
6121 ///
6122 /// The name only affects VMOs allocated after the name is set; this call
6123 /// does not rename existing VMOs. If multiple clients set different names
6124 /// then the larger priority value will win. Setting a new name with the
6125 /// same priority as a prior name doesn't change the name.
6126 ///
6127 /// All table fields are currently required.
6128 ///
6129 /// + request `priority` The name is only set if this is the first `SetName`
6130 /// or if `priority` is greater than any previous `priority` value in
6131 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
6132 /// + request `name` The name for VMOs created under this buffer collection.
6133 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
6134 self.client.send::<NodeSetNameRequest>(
6135 payload,
6136 0xb41f1624f48c1e9,
6137 fidl::encoding::DynamicFlags::FLEXIBLE,
6138 )
6139 }
6140
6141 /// Set information about the current client that can be used by sysmem to
6142 /// help diagnose leaking memory and allocation stalls waiting for a
6143 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
6144 ///
6145 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
6146 /// `Node`(s) derived from this `Node`, unless overriden by
6147 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
6148 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
6149 ///
6150 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
6151 /// `Allocator` is the most efficient way to ensure that all
6152 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
6153 /// set, and is also more efficient than separately sending the same debug
6154 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
6155 /// created [`fuchsia.sysmem2/Node`].
6156 ///
6157 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
6158 /// indicate which client is closing their channel first, leading to subtree
6159 /// failure (which can be normal if the purpose of the subtree is over, but
6160 /// if happening earlier than expected, the client-channel-specific name can
6161 /// help diagnose where the failure is first coming from, from sysmem's
6162 /// point of view).
6163 ///
6164 /// All table fields are currently required.
6165 ///
6166 /// + request `name` This can be an arbitrary string, but the current
6167 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
6168 /// + request `id` This can be an arbitrary id, but the current process ID
6169 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
6170 pub fn r#set_debug_client_info(
6171 &self,
6172 mut payload: &NodeSetDebugClientInfoRequest,
6173 ) -> Result<(), fidl::Error> {
6174 self.client.send::<NodeSetDebugClientInfoRequest>(
6175 payload,
6176 0x5cde8914608d99b1,
6177 fidl::encoding::DynamicFlags::FLEXIBLE,
6178 )
6179 }
6180
6181 /// Sysmem logs a warning if sysmem hasn't seen
6182 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
6183 /// within 5 seconds after creation of a new collection.
6184 ///
6185 /// Clients can call this method to change when the log is printed. If
6186 /// multiple client set the deadline, it's unspecified which deadline will
6187 /// take effect.
6188 ///
6189 /// In most cases the default works well.
6190 ///
6191 /// All table fields are currently required.
6192 ///
6193 /// + request `deadline` The time at which sysmem will start trying to log
6194 /// the warning, unless all constraints are with sysmem by then.
6195 pub fn r#set_debug_timeout_log_deadline(
6196 &self,
6197 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
6198 ) -> Result<(), fidl::Error> {
6199 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
6200 payload,
6201 0x716b0af13d5c0806,
6202 fidl::encoding::DynamicFlags::FLEXIBLE,
6203 )
6204 }
6205
6206 /// This enables verbose logging for the buffer collection.
6207 ///
6208 /// Verbose logging includes constraints set via
6209 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
6210 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
6211 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
6212 /// the tree of `Node`(s).
6213 ///
6214 /// Normally sysmem prints only a single line complaint when aggregation
6215 /// fails, with just the specific detailed reason that aggregation failed,
6216 /// with little surrounding context. While this is often enough to diagnose
6217 /// a problem if only a small change was made and everything was working
6218 /// before the small change, it's often not particularly helpful for getting
6219 /// a new buffer collection to work for the first time. Especially with
6220 /// more complex trees of nodes, involving things like
6221 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
6222 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
6223 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
6224 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
6225 /// looks like and why it's failing a logical allocation, or why a tree or
6226 /// subtree is failing sooner than expected.
6227 ///
6228 /// The intent of the extra logging is to be acceptable from a performance
6229 /// point of view, under the assumption that verbose logging is only enabled
6230 /// on a low number of buffer collections. If we're not tracking down a bug,
6231 /// we shouldn't send this message.
6232 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
6233 self.client.send::<fidl::encoding::EmptyPayload>(
6234 (),
6235 0x5209c77415b4dfad,
6236 fidl::encoding::DynamicFlags::FLEXIBLE,
6237 )
6238 }
6239
6240 /// This gets a handle that can be used as a parameter to
6241 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
6242 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
6243 /// client obtained this handle from this `Node`.
6244 ///
6245 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
6246 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
6247 /// despite the two calls typically being on different channels.
6248 ///
6249 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
6250 ///
6251 /// All table fields are currently required.
6252 ///
6253 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
6254 /// different `Node` channel, to prove that the client obtained the handle
6255 /// from this `Node`.
6256 pub fn r#get_node_ref(
6257 &self,
6258 ___deadline: zx::MonotonicInstant,
6259 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
6260 let _response = self.client.send_query::<
6261 fidl::encoding::EmptyPayload,
6262 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
6263 BufferCollectionTokenMarker,
6264 >(
6265 (),
6266 0x5b3d0e51614df053,
6267 fidl::encoding::DynamicFlags::FLEXIBLE,
6268 ___deadline,
6269 )?
6270 .into_result::<BufferCollectionTokenMarker>("get_node_ref")?;
6271 Ok(_response)
6272 }
6273
6274 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
6275 /// rooted at a different child token of a common parent
6276 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
6277 /// passed-in `node_ref`.
6278 ///
6279 /// This call is for assisting with admission control de-duplication, and
6280 /// with debugging.
6281 ///
6282 /// The `node_ref` must be obtained using
6283 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
6284 ///
6285 /// The `node_ref` can be a duplicated handle; it's not necessary to call
6286 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
6287 ///
6288 /// If a calling token may not actually be a valid token at all due to a
6289 /// potentially hostile/untrusted provider of the token, call
6290 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
6291 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
6292 /// never responds due to a calling token not being a real token (not really
6293 /// talking to sysmem). Another option is to call
6294 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
6295 /// which also validates the token along with converting it to a
6296 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
6297 ///
6298 /// All table fields are currently required.
6299 ///
6300 /// - response `is_alternate`
6301 /// - true: The first parent node in common between the calling node and
6302 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
6303 /// that the calling `Node` and the `node_ref` `Node` will not have both
6304 /// their constraints apply - rather sysmem will choose one or the other
6305 /// of the constraints - never both. This is because only one child of
6306 /// a `BufferCollectionTokenGroup` is selected during logical
6307 /// allocation, with only that one child's subtree contributing to
6308 /// constraints aggregation.
6309 /// - false: The first parent node in common between the calling `Node`
6310 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
6311 /// Currently, this means the first parent node in common is a
6312 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
6313 /// `Release`ed). This means that the calling `Node` and the `node_ref`
6314 /// `Node` may have both their constraints apply during constraints
6315 /// aggregation of the logical allocation, if both `Node`(s) are
6316 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
6317 /// this case, there is no `BufferCollectionTokenGroup` that will
6318 /// directly prevent the two `Node`(s) from both being selected and
6319 /// their constraints both aggregated, but even when false, one or both
6320 /// `Node`(s) may still be eliminated from consideration if one or both
6321 /// `Node`(s) has a direct or indirect parent
6322 /// `BufferCollectionTokenGroup` which selects a child subtree other
6323 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
6324 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
6325 /// associated with the same buffer collection as the calling `Node`.
6326 /// Another reason for this error is if the `node_ref` is an
6327 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
6328 /// a real `node_ref` obtained from `GetNodeRef`.
6329 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
6330 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
6331 /// the needed rights expected on a real `node_ref`.
6332 /// * No other failing status codes are returned by this call. However,
6333 /// sysmem may add additional codes in future, so the client should have
6334 /// sensible default handling for any failing status code.
6335 pub fn r#is_alternate_for(
6336 &self,
6337 mut payload: NodeIsAlternateForRequest,
6338 ___deadline: zx::MonotonicInstant,
6339 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
6340 let _response = self.client.send_query::<
6341 NodeIsAlternateForRequest,
6342 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
6343 BufferCollectionTokenMarker,
6344 >(
6345 &mut payload,
6346 0x3a58e00157e0825,
6347 fidl::encoding::DynamicFlags::FLEXIBLE,
6348 ___deadline,
6349 )?
6350 .into_result::<BufferCollectionTokenMarker>("is_alternate_for")?;
6351 Ok(_response.map(|x| x))
6352 }
6353
6354 /// Get the buffer collection ID. This ID is also available from
6355 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
6356 /// within the collection).
6357 ///
6358 /// This call is mainly useful in situations where we can't convey a
6359 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
6360 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
6361 /// handle, which can be joined back up with a `BufferCollection` client end
6362 /// that was created via a different path. Prefer to convey a
6363 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
6364 ///
6365 /// Trusting a `buffer_collection_id` value from a source other than sysmem
6366 /// is analogous to trusting a koid value from a source other than zircon.
6367 /// Both should be avoided unless really necessary, and both require
6368 /// caution. In some situations it may be reasonable to refer to a
6369 /// pre-established `BufferCollection` by `buffer_collection_id` via a
6370 /// protocol for efficiency reasons, but an incoming value purporting to be
6371 /// a `buffer_collection_id` is not sufficient alone to justify granting the
6372 /// sender of the `buffer_collection_id` any capability. The sender must
6373 /// first prove to a receiver that the sender has/had a VMO or has/had a
6374 /// `BufferCollectionToken` to the same collection by sending a handle that
6375 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
6376 /// `buffer_collection_id` value. The receiver should take care to avoid
6377 /// assuming that a sender had a `BufferCollectionToken` in cases where the
6378 /// sender has only proven that the sender had a VMO.
6379 ///
6380 /// - response `buffer_collection_id` This ID is unique per buffer
6381 /// collection per boot. Each buffer is uniquely identified by the
6382 /// `buffer_collection_id` and `buffer_index` together.
6383 pub fn r#get_buffer_collection_id(
6384 &self,
6385 ___deadline: zx::MonotonicInstant,
6386 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
6387 let _response = self.client.send_query::<
6388 fidl::encoding::EmptyPayload,
6389 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
6390 BufferCollectionTokenMarker,
6391 >(
6392 (),
6393 0x77d19a494b78ba8c,
6394 fidl::encoding::DynamicFlags::FLEXIBLE,
6395 ___deadline,
6396 )?
6397 .into_result::<BufferCollectionTokenMarker>("get_buffer_collection_id")?;
6398 Ok(_response)
6399 }
6400
6401 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
6402 /// created after this message to weak, which means that a client's `Node`
6403 /// client end (or a child created after this message) is not alone
6404 /// sufficient to keep allocated VMOs alive.
6405 ///
6406 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
6407 /// `close_weak_asap`.
6408 ///
6409 /// This message is only permitted before the `Node` becomes ready for
6410 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
6411 /// * `BufferCollectionToken`: any time
6412 /// * `BufferCollection`: before `SetConstraints`
6413 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
6414 ///
6415 /// Currently, no conversion from strong `Node` to weak `Node` after ready
6416 /// for allocation is provided, but a client can simulate that by creating
6417 /// an additional `Node` before allocation and setting that additional
6418 /// `Node` to weak, and then potentially at some point later sending
6419 /// `Release` and closing the client end of the client's strong `Node`, but
6420 /// keeping the client's weak `Node`.
6421 ///
6422 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
6423 /// collection failure (all `Node` client end(s) will see
6424 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
6425 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
6426 /// this situation until all `Node`(s) are ready for allocation. For initial
6427 /// allocation to succeed, at least one strong `Node` is required to exist
6428 /// at allocation time, but after that client receives VMO handles, that
6429 /// client can `BufferCollection.Release` and close the client end without
6430 /// causing this type of failure.
6431 ///
6432 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
6433 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
6434 /// separately as appropriate.
6435 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
6436 self.client.send::<fidl::encoding::EmptyPayload>(
6437 (),
6438 0x22dd3ea514eeffe1,
6439 fidl::encoding::DynamicFlags::FLEXIBLE,
6440 )
6441 }
6442
6443 /// This indicates to sysmem that the client is prepared to pay attention to
6444 /// `close_weak_asap`.
6445 ///
6446 /// If sent, this message must be before
6447 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
6448 ///
6449 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
6450 /// send this message before `WaitForAllBuffersAllocated`, or a parent
6451 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
6452 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
6453 /// trigger buffer collection failure.
6454 ///
6455 /// This message is necessary because weak sysmem VMOs have not always been
6456 /// a thing, so older clients are not aware of the need to pay attention to
6457 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
6458 /// sysmem weak VMO handles asap. By having this message and requiring
6459 /// participants to indicate their acceptance of this aspect of the overall
6460 /// protocol, we avoid situations where an older client is delivered a weak
6461 /// VMO without any way for sysmem to get that VMO to close quickly later
6462 /// (and on a per-buffer basis).
6463 ///
6464 /// A participant that doesn't handle `close_weak_asap` and also doesn't
6465 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
6466 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
6467 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
6468 /// same participant has a child/delegate which does retrieve VMOs, that
6469 /// child/delegate will need to send `SetWeakOk` before
6470 /// `WaitForAllBuffersAllocated`.
6471 ///
6472 /// + request `for_child_nodes_also` If present and true, this means direct
6473 /// child nodes of this node created after this message plus all
6474 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
6475 /// those nodes. Any child node of this node that was created before this
6476 /// message is not included. This setting is "sticky" in the sense that a
6477 /// subsequent `SetWeakOk` without this bool set to true does not reset
6478 /// the server-side bool. If this creates a problem for a participant, a
6479 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
6480 /// tokens instead, as appropriate. A participant should only set
6481 /// `for_child_nodes_also` true if the participant can really promise to
6482 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
6483 /// weak VMO handles held by participants holding the corresponding child
6484 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
6485 /// which are using sysmem(1) can be weak, despite the clients of those
6486 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
6487 /// direct way to find out about `close_weak_asap`. This only applies to
6488 /// descendents of this `Node` which are using sysmem(1), not to this
6489 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
6490 /// token, which will fail allocation unless an ancestor of this `Node`
6491 /// specified `for_child_nodes_also` true.
6492 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
6493 self.client.send::<NodeSetWeakOkRequest>(
6494 &mut payload,
6495 0x38a44fc4d7724be9,
6496 fidl::encoding::DynamicFlags::FLEXIBLE,
6497 )
6498 }
6499
6500 /// The server_end will be closed after this `Node` and any child nodes have
6501 /// have released their buffer counts, making those counts available for
6502 /// reservation by a different `Node` via
6503 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
6504 ///
6505 /// The `Node` buffer counts may not be released until the entire tree of
6506 /// `Node`(s) is closed or failed, because
6507 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
6508 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
6509 /// `Node` buffer counts remain reserved until the orphaned node is later
6510 /// cleaned up.
6511 ///
6512 /// If the `Node` exceeds a fairly large number of attached eventpair server
6513 /// ends, a log message will indicate this and the `Node` (and the
6514 /// appropriate) sub-tree will fail.
6515 ///
6516 /// The `server_end` will remain open when
6517 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
6518 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
6519 /// [`fuchsia.sysmem2/BufferCollection`].
6520 ///
6521 /// This message can also be used with a
6522 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
6523 pub fn r#attach_node_tracking(
6524 &self,
6525 mut payload: NodeAttachNodeTrackingRequest,
6526 ) -> Result<(), fidl::Error> {
6527 self.client.send::<NodeAttachNodeTrackingRequest>(
6528 &mut payload,
6529 0x3f22f2a293d3cdac,
6530 fidl::encoding::DynamicFlags::FLEXIBLE,
6531 )
6532 }
6533
6534 /// Create additional [`fuchsia.sysmem2/BufferCollectionToken`](s) from this
6535 /// one, referring to the same buffer collection.
6536 ///
6537 /// The created tokens are children of this token in the
6538 /// [`fuchsia.sysmem2/Node`] heirarchy.
6539 ///
6540 /// This method can be used to add more participants, by transferring the
6541 /// newly created tokens to additional participants.
6542 ///
6543 /// A new token will be returned for each entry in the
6544 /// `rights_attenuation_masks` array.
6545 ///
6546 /// If the called token may not actually be a valid token due to a
6547 /// potentially hostile/untrusted provider of the token, consider using
6548 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
6549 /// instead of potentially getting stuck indefinitely if
6550 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] never responds
6551 /// due to the calling token not being a real token.
6552 ///
6553 /// In contrast to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], no
6554 /// separate [`fuchsia.sysmem2/Node.Sync`] is needed after calling this
6555 /// method, because the sync step is included in this call, at the cost of a
6556 /// round trip during this call.
6557 ///
6558 /// All tokens must be turned in to sysmem via
6559 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
6560 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
6561 /// successfully allocate buffers (or to logically allocate buffers in the
6562 /// case of subtrees involving
6563 /// [`fuchsia.sysmem2/BufferCollectionToken.AttachToken`]).
6564 ///
6565 /// All table fields are currently required.
6566 ///
6567 /// + request `rights_attenuation_mask` In each entry of
6568 /// `rights_attenuation_masks`, rights bits that are zero will be absent
6569 /// in the buffer VMO rights obtainable via the corresponding returned
6570 /// token. This allows an initiator or intermediary participant to
6571 /// attenuate the rights available to a participant. This does not allow a
6572 /// participant to gain rights that the participant doesn't already have.
6573 /// The value `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no
6574 /// attenuation should be applied.
6575 /// - response `tokens` The client ends of each newly created token.
6576 pub fn r#duplicate_sync(
6577 &self,
6578 mut payload: &BufferCollectionTokenDuplicateSyncRequest,
6579 ___deadline: zx::MonotonicInstant,
6580 ) -> Result<BufferCollectionTokenDuplicateSyncResponse, fidl::Error> {
6581 let _response = self.client.send_query::<
6582 BufferCollectionTokenDuplicateSyncRequest,
6583 fidl::encoding::FlexibleType<BufferCollectionTokenDuplicateSyncResponse>,
6584 BufferCollectionTokenMarker,
6585 >(
6586 payload,
6587 0x1c1af9919d1ca45c,
6588 fidl::encoding::DynamicFlags::FLEXIBLE,
6589 ___deadline,
6590 )?
6591 .into_result::<BufferCollectionTokenMarker>("duplicate_sync")?;
6592 Ok(_response)
6593 }
6594
6595 /// Create an additional [`fuchsia.sysmem2/BufferCollectionToken`] from this
6596 /// one, referring to the same buffer collection.
6597 ///
6598 /// The created token is a child of this token in the
6599 /// [`fuchsia.sysmem2/Node`] heirarchy.
6600 ///
6601 /// This method can be used to add a participant, by transferring the newly
6602 /// created token to another participant.
6603 ///
6604 /// This one-way message can be used instead of the two-way
6605 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] FIDL call in
6606 /// performance sensitive cases where it would be undesireable to wait for
6607 /// sysmem to respond to
6608 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] or when the
6609 /// client code isn't structured to make it easy to duplicate all the needed
6610 /// tokens at once.
6611 ///
6612 /// After sending one or more `Duplicate` messages, and before sending the
6613 /// newly created child tokens to other participants (or to other
6614 /// [`fuchsia.sysmem2/Allocator`] channels), the client must send a
6615 /// [`fuchsia.sysmem2/Node.Sync`] and wait for the `Sync` response. The
6616 /// `Sync` call can be made on the token, or on the `BufferCollection`
6617 /// obtained by passing this token to `BindSharedCollection`. Either will
6618 /// ensure that the server knows about the tokens created via `Duplicate`
6619 /// before the other participant sends the token to the server via separate
6620 /// `Allocator` channel.
6621 ///
6622 /// All tokens must be turned in via
6623 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
6624 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
6625 /// successfully allocate buffers.
6626 ///
6627 /// All table fields are currently required.
6628 ///
6629 /// + request `rights_attenuation_mask` The rights bits that are zero in
6630 /// this mask will be absent in the buffer VMO rights obtainable via the
6631 /// client end of `token_request`. This allows an initiator or
6632 /// intermediary participant to attenuate the rights available to a
6633 /// delegate participant. This does not allow a participant to gain rights
6634 /// that the participant doesn't already have. The value
6635 /// `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no attenuation
6636 /// should be applied.
6637 /// + These values for rights_attenuation_mask result in no attenuation:
6638 /// + `ZX_RIGHT_SAME_RIGHTS` (preferred)
6639 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is
6640 /// computed)
6641 /// + 0 (deprecated - do not use 0 - an ERROR will go to the log)
6642 /// + request `token_request` is the server end of a `BufferCollectionToken`
6643 /// channel. The client end of this channel acts as another participant in
6644 /// the shared buffer collection.
6645 pub fn r#duplicate(
6646 &self,
6647 mut payload: BufferCollectionTokenDuplicateRequest,
6648 ) -> Result<(), fidl::Error> {
6649 self.client.send::<BufferCollectionTokenDuplicateRequest>(
6650 &mut payload,
6651 0x73e78f92ee7fb887,
6652 fidl::encoding::DynamicFlags::FLEXIBLE,
6653 )
6654 }
6655
6656 /// Set this [`fuchsia.sysmem2/BufferCollectionToken`] to dispensable.
6657 ///
6658 /// When the `BufferCollectionToken` is converted to a
6659 /// [`fuchsia.sysmem2/BufferCollection`], the dispensable status applies to
6660 /// the `BufferCollection` also.
6661 ///
6662 /// Normally, if a client closes a [`fuchsia.sysmem2/BufferCollection`]
6663 /// client end without having sent
6664 /// [`fuchsia.sysmem2/BufferCollection.Release`] first, the
6665 /// `BufferCollection` [`fuchisa.sysmem2/Node`] will fail, which also
6666 /// propagates failure to the parent [`fuchsia.sysmem2/Node`] and so on up
6667 /// to the root `Node`, which fails the whole buffer collection. In
6668 /// contrast, a dispensable `Node` can fail after buffers are allocated
6669 /// without causing failure of its parent in the [`fuchsia.sysmem2/Node`]
6670 /// heirarchy.
6671 ///
6672 /// The dispensable `Node` participates in constraints aggregation along
6673 /// with its parent before buffer allocation. If the dispensable `Node`
6674 /// fails before buffers are allocated, the failure propagates to the
6675 /// dispensable `Node`'s parent.
6676 ///
6677 /// After buffers are allocated, failure of the dispensable `Node` (or any
6678 /// child of the dispensable `Node`) does not propagate to the dispensable
6679 /// `Node`'s parent. Failure does propagate from a normal child of a
6680 /// dispensable `Node` to the dispensable `Node`. Failure of a child is
6681 /// blocked from reaching its parent if the child is attached using
6682 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or if the child is
6683 /// dispensable and the failure occurred after allocation.
6684 ///
6685 /// A dispensable `Node` can be used in cases where a participant needs to
6686 /// provide constraints, but after buffers are allocated, the participant
6687 /// can fail without causing buffer collection failure from the parent
6688 /// `Node`'s point of view.
6689 ///
6690 /// In contrast, `BufferCollection.AttachToken` can be used to create a
6691 /// `BufferCollectionToken` which does not participate in constraints
6692 /// aggregation with its parent `Node`, and whose failure at any time does
6693 /// not propagate to its parent `Node`, and whose potential delay providing
6694 /// constraints does not prevent the parent `Node` from completing its
6695 /// buffer allocation.
6696 ///
6697 /// An initiator (creator of the root `Node` using
6698 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`]) may in some
6699 /// scenarios choose to initially use a dispensable `Node` for a first
6700 /// instance of a participant, and then later if the first instance of that
6701 /// participant fails, a new second instance of that participant my be given
6702 /// a `BufferCollectionToken` created with `AttachToken`.
6703 ///
6704 /// Normally a client will `SetDispensable` on a `BufferCollectionToken`
6705 /// shortly before sending the dispensable `BufferCollectionToken` to a
6706 /// delegate participant. Because `SetDispensable` prevents propagation of
6707 /// child `Node` failure to parent `Node`(s), if the client was relying on
6708 /// noticing child failure via failure of the parent `Node` retained by the
6709 /// client, the client may instead need to notice failure via other means.
6710 /// If other means aren't available/convenient, the client can instead
6711 /// retain the dispensable `Node` and create a child `Node` under that to
6712 /// send to the delegate participant, retaining this `Node` in order to
6713 /// notice failure of the subtree rooted at this `Node` via this `Node`'s
6714 /// ZX_CHANNEL_PEER_CLOSED signal, and take whatever action is appropriate
6715 /// (e.g. starting a new instance of the delegate participant and handing it
6716 /// a `BufferCollectionToken` created using
6717 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or propagate failure
6718 /// and clean up in a client-specific way).
6719 ///
6720 /// While it is possible (and potentially useful) to `SetDispensable` on a
6721 /// direct child of a `BufferCollectionTokenGroup` `Node`, it isn't possible
6722 /// to later replace a failed dispensable `Node` that was a direct child of
6723 /// a `BufferCollectionTokenGroup` with a new token using `AttachToken`
6724 /// (since there's no `AttachToken` on a group). Instead, to enable
6725 /// `AttachToken` replacement in this case, create an additional
6726 /// non-dispensable token that's a direct child of the group and make the
6727 /// existing dispensable token a child of the additional token. This way,
6728 /// the additional token that is a direct child of the group has
6729 /// `BufferCollection.AttachToken` which can be used to replace the failed
6730 /// dispensable token.
6731 ///
6732 /// `SetDispensable` on an already-dispensable token is idempotent.
6733 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
6734 self.client.send::<fidl::encoding::EmptyPayload>(
6735 (),
6736 0x228acf979254df8b,
6737 fidl::encoding::DynamicFlags::FLEXIBLE,
6738 )
6739 }
6740
6741 /// Create a logical OR among a set of tokens, called a
6742 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
6743 ///
6744 /// Most sysmem clients and many participants don't need to care about this
6745 /// message or about `BufferCollectionTokenGroup`(s). However, in some cases
6746 /// a participant wants to attempt to include one set of delegate
6747 /// participants, but if constraints don't combine successfully that way,
6748 /// fall back to a different (possibly overlapping) set of delegate
6749 /// participants, and/or fall back to a less demanding strategy (in terms of
6750 /// how strict the [`fuchisa.sysmem2/BufferCollectionConstraints`] are,
6751 /// across all involved delegate participants). In such cases, a
6752 /// `BufferCollectionTokenGroup` is useful.
6753 ///
6754 /// A `BufferCollectionTokenGroup` is used to create a 1 of N OR among N
6755 /// child [`fuchsia.sysmem2/BufferCollectionToken`](s). The child tokens
6756 /// which are not selected during aggregation will fail (close), which a
6757 /// potential participant should notice when their `BufferCollection`
6758 /// channel client endpoint sees PEER_CLOSED, allowing the participant to
6759 /// clean up the speculative usage that didn't end up happening (this is
6760 /// simimlar to a normal `BufferCollection` server end closing on failure to
6761 /// allocate a logical buffer collection or later async failure of a buffer
6762 /// collection).
6763 ///
6764 /// See comments on protocol `BufferCollectionTokenGroup`.
6765 ///
6766 /// Any `rights_attenuation_mask` or `AttachToken`/`SetDispensable` to be
6767 /// applied to the whole group can be achieved with a
6768 /// `BufferCollectionToken` for this purpose as a direct parent of the
6769 /// `BufferCollectionTokenGroup`.
6770 ///
6771 /// All table fields are currently required.
6772 ///
6773 /// + request `group_request` The server end of a
6774 /// `BufferCollectionTokenGroup` channel to be served by sysmem.
6775 pub fn r#create_buffer_collection_token_group(
6776 &self,
6777 mut payload: BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
6778 ) -> Result<(), fidl::Error> {
6779 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
6780 &mut payload,
6781 0x30f8d48e77bd36f2,
6782 fidl::encoding::DynamicFlags::FLEXIBLE,
6783 )
6784 }
6785}
6786
6787#[cfg(target_os = "fuchsia")]
6788impl From<BufferCollectionTokenSynchronousProxy> for zx::NullableHandle {
6789 fn from(value: BufferCollectionTokenSynchronousProxy) -> Self {
6790 value.into_channel().into()
6791 }
6792}
6793
6794#[cfg(target_os = "fuchsia")]
6795impl From<fidl::Channel> for BufferCollectionTokenSynchronousProxy {
6796 fn from(value: fidl::Channel) -> Self {
6797 Self::new(value)
6798 }
6799}
6800
6801#[cfg(target_os = "fuchsia")]
6802impl fidl::endpoints::FromClient for BufferCollectionTokenSynchronousProxy {
6803 type Protocol = BufferCollectionTokenMarker;
6804
6805 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>) -> Self {
6806 Self::new(value.into_channel())
6807 }
6808}
6809
6810#[derive(Debug, Clone)]
6811pub struct BufferCollectionTokenProxy {
6812 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
6813}
6814
6815impl fidl::endpoints::Proxy for BufferCollectionTokenProxy {
6816 type Protocol = BufferCollectionTokenMarker;
6817
6818 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
6819 Self::new(inner)
6820 }
6821
6822 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
6823 self.client.into_channel().map_err(|client| Self { client })
6824 }
6825
6826 fn as_channel(&self) -> &::fidl::AsyncChannel {
6827 self.client.as_channel()
6828 }
6829}
6830
6831impl BufferCollectionTokenProxy {
6832 /// Create a new Proxy for fuchsia.sysmem2/BufferCollectionToken.
6833 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
6834 let protocol_name =
6835 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
6836 Self { client: fidl::client::Client::new(channel, protocol_name) }
6837 }
6838
6839 /// Get a Stream of events from the remote end of the protocol.
6840 ///
6841 /// # Panics
6842 ///
6843 /// Panics if the event stream was already taken.
6844 pub fn take_event_stream(&self) -> BufferCollectionTokenEventStream {
6845 BufferCollectionTokenEventStream { event_receiver: self.client.take_event_receiver() }
6846 }
6847
6848 /// Ensure that previous messages have been received server side. This is
6849 /// particularly useful after previous messages that created new tokens,
6850 /// because a token must be known to the sysmem server before sending the
6851 /// token to another participant.
6852 ///
6853 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
6854 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
6855 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
6856 /// to mitigate the possibility of a hostile/fake
6857 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
6858 /// Another way is to pass the token to
6859 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
6860 /// the token as part of exchanging it for a
6861 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
6862 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
6863 /// of stalling.
6864 ///
6865 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
6866 /// and then starting and completing a `Sync`, it's then safe to send the
6867 /// `BufferCollectionToken` client ends to other participants knowing the
6868 /// server will recognize the tokens when they're sent by the other
6869 /// participants to sysmem in a
6870 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
6871 /// efficient way to create tokens while avoiding unnecessary round trips.
6872 ///
6873 /// Other options include waiting for each
6874 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
6875 /// individually (using separate call to `Sync` after each), or calling
6876 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
6877 /// converted to a `BufferCollection` via
6878 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
6879 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
6880 /// the sync step and can create multiple tokens at once.
6881 pub fn r#sync(
6882 &self,
6883 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
6884 BufferCollectionTokenProxyInterface::r#sync(self)
6885 }
6886
6887 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
6888 ///
6889 /// Normally a participant will convert a `BufferCollectionToken` into a
6890 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
6891 /// `Release` via the token (and then close the channel immediately or
6892 /// shortly later in response to server closing the server end), which
6893 /// avoids causing buffer collection failure. Without a prior `Release`,
6894 /// closing the `BufferCollectionToken` client end will cause buffer
6895 /// collection failure.
6896 ///
6897 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
6898 ///
6899 /// By default the server handles unexpected closure of a
6900 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
6901 /// first) by failing the buffer collection. Partly this is to expedite
6902 /// closing VMO handles to reclaim memory when any participant fails. If a
6903 /// participant would like to cleanly close a `BufferCollection` without
6904 /// causing buffer collection failure, the participant can send `Release`
6905 /// before closing the `BufferCollection` client end. The `Release` can
6906 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
6907 /// buffer collection won't require constraints from this node in order to
6908 /// allocate. If after `SetConstraints`, the constraints are retained and
6909 /// aggregated, despite the lack of `BufferCollection` connection at the
6910 /// time of constraints aggregation.
6911 ///
6912 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
6913 ///
6914 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
6915 /// end (without `Release` first) will trigger failure of the buffer
6916 /// collection. To close a `BufferCollectionTokenGroup` channel without
6917 /// failing the buffer collection, ensure that AllChildrenPresent() has been
6918 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
6919 /// client end.
6920 ///
6921 /// If `Release` occurs before
6922 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
6923 /// buffer collection will fail (triggered by reception of `Release` without
6924 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
6925 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
6926 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
6927 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
6928 /// close requires `AllChildrenPresent` (if not already sent), then
6929 /// `Release`, then close client end.
6930 ///
6931 /// If `Release` occurs after `AllChildrenPresent`, the children and all
6932 /// their constraints remain intact (just as they would if the
6933 /// `BufferCollectionTokenGroup` channel had remained open), and the client
6934 /// end close doesn't trigger buffer collection failure.
6935 ///
6936 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
6937 ///
6938 /// For brevity, the per-channel-protocol paragraphs above ignore the
6939 /// separate failure domain created by
6940 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
6941 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
6942 /// unexpectedly closes (without `Release` first) and that client end is
6943 /// under a failure domain, instead of failing the whole buffer collection,
6944 /// the failure domain is failed, but the buffer collection itself is
6945 /// isolated from failure of the failure domain. Such failure domains can be
6946 /// nested, in which case only the inner-most failure domain in which the
6947 /// `Node` resides fails.
6948 pub fn r#release(&self) -> Result<(), fidl::Error> {
6949 BufferCollectionTokenProxyInterface::r#release(self)
6950 }
6951
6952 /// Set a name for VMOs in this buffer collection.
6953 ///
6954 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
6955 /// will be truncated to fit. The name of the vmo will be suffixed with the
6956 /// buffer index within the collection (if the suffix fits within
6957 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
6958 /// listed in the inspect data.
6959 ///
6960 /// The name only affects VMOs allocated after the name is set; this call
6961 /// does not rename existing VMOs. If multiple clients set different names
6962 /// then the larger priority value will win. Setting a new name with the
6963 /// same priority as a prior name doesn't change the name.
6964 ///
6965 /// All table fields are currently required.
6966 ///
6967 /// + request `priority` The name is only set if this is the first `SetName`
6968 /// or if `priority` is greater than any previous `priority` value in
6969 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
6970 /// + request `name` The name for VMOs created under this buffer collection.
6971 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
6972 BufferCollectionTokenProxyInterface::r#set_name(self, payload)
6973 }
6974
6975 /// Set information about the current client that can be used by sysmem to
6976 /// help diagnose leaking memory and allocation stalls waiting for a
6977 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
6978 ///
6979 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
6980 /// `Node`(s) derived from this `Node`, unless overriden by
6981 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
6982 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
6983 ///
6984 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
6985 /// `Allocator` is the most efficient way to ensure that all
6986 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
6987 /// set, and is also more efficient than separately sending the same debug
6988 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
6989 /// created [`fuchsia.sysmem2/Node`].
6990 ///
6991 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
6992 /// indicate which client is closing their channel first, leading to subtree
6993 /// failure (which can be normal if the purpose of the subtree is over, but
6994 /// if happening earlier than expected, the client-channel-specific name can
6995 /// help diagnose where the failure is first coming from, from sysmem's
6996 /// point of view).
6997 ///
6998 /// All table fields are currently required.
6999 ///
7000 /// + request `name` This can be an arbitrary string, but the current
7001 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
7002 /// + request `id` This can be an arbitrary id, but the current process ID
7003 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
7004 pub fn r#set_debug_client_info(
7005 &self,
7006 mut payload: &NodeSetDebugClientInfoRequest,
7007 ) -> Result<(), fidl::Error> {
7008 BufferCollectionTokenProxyInterface::r#set_debug_client_info(self, payload)
7009 }
7010
7011 /// Sysmem logs a warning if sysmem hasn't seen
7012 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
7013 /// within 5 seconds after creation of a new collection.
7014 ///
7015 /// Clients can call this method to change when the log is printed. If
7016 /// multiple client set the deadline, it's unspecified which deadline will
7017 /// take effect.
7018 ///
7019 /// In most cases the default works well.
7020 ///
7021 /// All table fields are currently required.
7022 ///
7023 /// + request `deadline` The time at which sysmem will start trying to log
7024 /// the warning, unless all constraints are with sysmem by then.
7025 pub fn r#set_debug_timeout_log_deadline(
7026 &self,
7027 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
7028 ) -> Result<(), fidl::Error> {
7029 BufferCollectionTokenProxyInterface::r#set_debug_timeout_log_deadline(self, payload)
7030 }
7031
7032 /// This enables verbose logging for the buffer collection.
7033 ///
7034 /// Verbose logging includes constraints set via
7035 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
7036 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
7037 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
7038 /// the tree of `Node`(s).
7039 ///
7040 /// Normally sysmem prints only a single line complaint when aggregation
7041 /// fails, with just the specific detailed reason that aggregation failed,
7042 /// with little surrounding context. While this is often enough to diagnose
7043 /// a problem if only a small change was made and everything was working
7044 /// before the small change, it's often not particularly helpful for getting
7045 /// a new buffer collection to work for the first time. Especially with
7046 /// more complex trees of nodes, involving things like
7047 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
7048 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
7049 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
7050 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
7051 /// looks like and why it's failing a logical allocation, or why a tree or
7052 /// subtree is failing sooner than expected.
7053 ///
7054 /// The intent of the extra logging is to be acceptable from a performance
7055 /// point of view, under the assumption that verbose logging is only enabled
7056 /// on a low number of buffer collections. If we're not tracking down a bug,
7057 /// we shouldn't send this message.
7058 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7059 BufferCollectionTokenProxyInterface::r#set_verbose_logging(self)
7060 }
7061
7062 /// This gets a handle that can be used as a parameter to
7063 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
7064 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
7065 /// client obtained this handle from this `Node`.
7066 ///
7067 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
7068 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
7069 /// despite the two calls typically being on different channels.
7070 ///
7071 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
7072 ///
7073 /// All table fields are currently required.
7074 ///
7075 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
7076 /// different `Node` channel, to prove that the client obtained the handle
7077 /// from this `Node`.
7078 pub fn r#get_node_ref(
7079 &self,
7080 ) -> fidl::client::QueryResponseFut<
7081 NodeGetNodeRefResponse,
7082 fidl::encoding::DefaultFuchsiaResourceDialect,
7083 > {
7084 BufferCollectionTokenProxyInterface::r#get_node_ref(self)
7085 }
7086
7087 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
7088 /// rooted at a different child token of a common parent
7089 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
7090 /// passed-in `node_ref`.
7091 ///
7092 /// This call is for assisting with admission control de-duplication, and
7093 /// with debugging.
7094 ///
7095 /// The `node_ref` must be obtained using
7096 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
7097 ///
7098 /// The `node_ref` can be a duplicated handle; it's not necessary to call
7099 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
7100 ///
7101 /// If a calling token may not actually be a valid token at all due to a
7102 /// potentially hostile/untrusted provider of the token, call
7103 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
7104 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
7105 /// never responds due to a calling token not being a real token (not really
7106 /// talking to sysmem). Another option is to call
7107 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
7108 /// which also validates the token along with converting it to a
7109 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
7110 ///
7111 /// All table fields are currently required.
7112 ///
7113 /// - response `is_alternate`
7114 /// - true: The first parent node in common between the calling node and
7115 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
7116 /// that the calling `Node` and the `node_ref` `Node` will not have both
7117 /// their constraints apply - rather sysmem will choose one or the other
7118 /// of the constraints - never both. This is because only one child of
7119 /// a `BufferCollectionTokenGroup` is selected during logical
7120 /// allocation, with only that one child's subtree contributing to
7121 /// constraints aggregation.
7122 /// - false: The first parent node in common between the calling `Node`
7123 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
7124 /// Currently, this means the first parent node in common is a
7125 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
7126 /// `Release`ed). This means that the calling `Node` and the `node_ref`
7127 /// `Node` may have both their constraints apply during constraints
7128 /// aggregation of the logical allocation, if both `Node`(s) are
7129 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
7130 /// this case, there is no `BufferCollectionTokenGroup` that will
7131 /// directly prevent the two `Node`(s) from both being selected and
7132 /// their constraints both aggregated, but even when false, one or both
7133 /// `Node`(s) may still be eliminated from consideration if one or both
7134 /// `Node`(s) has a direct or indirect parent
7135 /// `BufferCollectionTokenGroup` which selects a child subtree other
7136 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
7137 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
7138 /// associated with the same buffer collection as the calling `Node`.
7139 /// Another reason for this error is if the `node_ref` is an
7140 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
7141 /// a real `node_ref` obtained from `GetNodeRef`.
7142 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
7143 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
7144 /// the needed rights expected on a real `node_ref`.
7145 /// * No other failing status codes are returned by this call. However,
7146 /// sysmem may add additional codes in future, so the client should have
7147 /// sensible default handling for any failing status code.
7148 pub fn r#is_alternate_for(
7149 &self,
7150 mut payload: NodeIsAlternateForRequest,
7151 ) -> fidl::client::QueryResponseFut<
7152 NodeIsAlternateForResult,
7153 fidl::encoding::DefaultFuchsiaResourceDialect,
7154 > {
7155 BufferCollectionTokenProxyInterface::r#is_alternate_for(self, payload)
7156 }
7157
7158 /// Get the buffer collection ID. This ID is also available from
7159 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
7160 /// within the collection).
7161 ///
7162 /// This call is mainly useful in situations where we can't convey a
7163 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
7164 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
7165 /// handle, which can be joined back up with a `BufferCollection` client end
7166 /// that was created via a different path. Prefer to convey a
7167 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
7168 ///
7169 /// Trusting a `buffer_collection_id` value from a source other than sysmem
7170 /// is analogous to trusting a koid value from a source other than zircon.
7171 /// Both should be avoided unless really necessary, and both require
7172 /// caution. In some situations it may be reasonable to refer to a
7173 /// pre-established `BufferCollection` by `buffer_collection_id` via a
7174 /// protocol for efficiency reasons, but an incoming value purporting to be
7175 /// a `buffer_collection_id` is not sufficient alone to justify granting the
7176 /// sender of the `buffer_collection_id` any capability. The sender must
7177 /// first prove to a receiver that the sender has/had a VMO or has/had a
7178 /// `BufferCollectionToken` to the same collection by sending a handle that
7179 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
7180 /// `buffer_collection_id` value. The receiver should take care to avoid
7181 /// assuming that a sender had a `BufferCollectionToken` in cases where the
7182 /// sender has only proven that the sender had a VMO.
7183 ///
7184 /// - response `buffer_collection_id` This ID is unique per buffer
7185 /// collection per boot. Each buffer is uniquely identified by the
7186 /// `buffer_collection_id` and `buffer_index` together.
7187 pub fn r#get_buffer_collection_id(
7188 &self,
7189 ) -> fidl::client::QueryResponseFut<
7190 NodeGetBufferCollectionIdResponse,
7191 fidl::encoding::DefaultFuchsiaResourceDialect,
7192 > {
7193 BufferCollectionTokenProxyInterface::r#get_buffer_collection_id(self)
7194 }
7195
7196 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
7197 /// created after this message to weak, which means that a client's `Node`
7198 /// client end (or a child created after this message) is not alone
7199 /// sufficient to keep allocated VMOs alive.
7200 ///
7201 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
7202 /// `close_weak_asap`.
7203 ///
7204 /// This message is only permitted before the `Node` becomes ready for
7205 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
7206 /// * `BufferCollectionToken`: any time
7207 /// * `BufferCollection`: before `SetConstraints`
7208 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
7209 ///
7210 /// Currently, no conversion from strong `Node` to weak `Node` after ready
7211 /// for allocation is provided, but a client can simulate that by creating
7212 /// an additional `Node` before allocation and setting that additional
7213 /// `Node` to weak, and then potentially at some point later sending
7214 /// `Release` and closing the client end of the client's strong `Node`, but
7215 /// keeping the client's weak `Node`.
7216 ///
7217 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
7218 /// collection failure (all `Node` client end(s) will see
7219 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
7220 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
7221 /// this situation until all `Node`(s) are ready for allocation. For initial
7222 /// allocation to succeed, at least one strong `Node` is required to exist
7223 /// at allocation time, but after that client receives VMO handles, that
7224 /// client can `BufferCollection.Release` and close the client end without
7225 /// causing this type of failure.
7226 ///
7227 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
7228 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
7229 /// separately as appropriate.
7230 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
7231 BufferCollectionTokenProxyInterface::r#set_weak(self)
7232 }
7233
7234 /// This indicates to sysmem that the client is prepared to pay attention to
7235 /// `close_weak_asap`.
7236 ///
7237 /// If sent, this message must be before
7238 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
7239 ///
7240 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
7241 /// send this message before `WaitForAllBuffersAllocated`, or a parent
7242 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
7243 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
7244 /// trigger buffer collection failure.
7245 ///
7246 /// This message is necessary because weak sysmem VMOs have not always been
7247 /// a thing, so older clients are not aware of the need to pay attention to
7248 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
7249 /// sysmem weak VMO handles asap. By having this message and requiring
7250 /// participants to indicate their acceptance of this aspect of the overall
7251 /// protocol, we avoid situations where an older client is delivered a weak
7252 /// VMO without any way for sysmem to get that VMO to close quickly later
7253 /// (and on a per-buffer basis).
7254 ///
7255 /// A participant that doesn't handle `close_weak_asap` and also doesn't
7256 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
7257 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
7258 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
7259 /// same participant has a child/delegate which does retrieve VMOs, that
7260 /// child/delegate will need to send `SetWeakOk` before
7261 /// `WaitForAllBuffersAllocated`.
7262 ///
7263 /// + request `for_child_nodes_also` If present and true, this means direct
7264 /// child nodes of this node created after this message plus all
7265 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
7266 /// those nodes. Any child node of this node that was created before this
7267 /// message is not included. This setting is "sticky" in the sense that a
7268 /// subsequent `SetWeakOk` without this bool set to true does not reset
7269 /// the server-side bool. If this creates a problem for a participant, a
7270 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
7271 /// tokens instead, as appropriate. A participant should only set
7272 /// `for_child_nodes_also` true if the participant can really promise to
7273 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
7274 /// weak VMO handles held by participants holding the corresponding child
7275 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
7276 /// which are using sysmem(1) can be weak, despite the clients of those
7277 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
7278 /// direct way to find out about `close_weak_asap`. This only applies to
7279 /// descendents of this `Node` which are using sysmem(1), not to this
7280 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
7281 /// token, which will fail allocation unless an ancestor of this `Node`
7282 /// specified `for_child_nodes_also` true.
7283 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
7284 BufferCollectionTokenProxyInterface::r#set_weak_ok(self, payload)
7285 }
7286
7287 /// The server_end will be closed after this `Node` and any child nodes have
7288 /// have released their buffer counts, making those counts available for
7289 /// reservation by a different `Node` via
7290 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
7291 ///
7292 /// The `Node` buffer counts may not be released until the entire tree of
7293 /// `Node`(s) is closed or failed, because
7294 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
7295 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
7296 /// `Node` buffer counts remain reserved until the orphaned node is later
7297 /// cleaned up.
7298 ///
7299 /// If the `Node` exceeds a fairly large number of attached eventpair server
7300 /// ends, a log message will indicate this and the `Node` (and the
7301 /// appropriate) sub-tree will fail.
7302 ///
7303 /// The `server_end` will remain open when
7304 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
7305 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
7306 /// [`fuchsia.sysmem2/BufferCollection`].
7307 ///
7308 /// This message can also be used with a
7309 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
7310 pub fn r#attach_node_tracking(
7311 &self,
7312 mut payload: NodeAttachNodeTrackingRequest,
7313 ) -> Result<(), fidl::Error> {
7314 BufferCollectionTokenProxyInterface::r#attach_node_tracking(self, payload)
7315 }
7316
7317 /// Create additional [`fuchsia.sysmem2/BufferCollectionToken`](s) from this
7318 /// one, referring to the same buffer collection.
7319 ///
7320 /// The created tokens are children of this token in the
7321 /// [`fuchsia.sysmem2/Node`] heirarchy.
7322 ///
7323 /// This method can be used to add more participants, by transferring the
7324 /// newly created tokens to additional participants.
7325 ///
7326 /// A new token will be returned for each entry in the
7327 /// `rights_attenuation_masks` array.
7328 ///
7329 /// If the called token may not actually be a valid token due to a
7330 /// potentially hostile/untrusted provider of the token, consider using
7331 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
7332 /// instead of potentially getting stuck indefinitely if
7333 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] never responds
7334 /// due to the calling token not being a real token.
7335 ///
7336 /// In contrast to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], no
7337 /// separate [`fuchsia.sysmem2/Node.Sync`] is needed after calling this
7338 /// method, because the sync step is included in this call, at the cost of a
7339 /// round trip during this call.
7340 ///
7341 /// All tokens must be turned in to sysmem via
7342 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
7343 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
7344 /// successfully allocate buffers (or to logically allocate buffers in the
7345 /// case of subtrees involving
7346 /// [`fuchsia.sysmem2/BufferCollectionToken.AttachToken`]).
7347 ///
7348 /// All table fields are currently required.
7349 ///
7350 /// + request `rights_attenuation_mask` In each entry of
7351 /// `rights_attenuation_masks`, rights bits that are zero will be absent
7352 /// in the buffer VMO rights obtainable via the corresponding returned
7353 /// token. This allows an initiator or intermediary participant to
7354 /// attenuate the rights available to a participant. This does not allow a
7355 /// participant to gain rights that the participant doesn't already have.
7356 /// The value `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no
7357 /// attenuation should be applied.
7358 /// - response `tokens` The client ends of each newly created token.
7359 pub fn r#duplicate_sync(
7360 &self,
7361 mut payload: &BufferCollectionTokenDuplicateSyncRequest,
7362 ) -> fidl::client::QueryResponseFut<
7363 BufferCollectionTokenDuplicateSyncResponse,
7364 fidl::encoding::DefaultFuchsiaResourceDialect,
7365 > {
7366 BufferCollectionTokenProxyInterface::r#duplicate_sync(self, payload)
7367 }
7368
7369 /// Create an additional [`fuchsia.sysmem2/BufferCollectionToken`] from this
7370 /// one, referring to the same buffer collection.
7371 ///
7372 /// The created token is a child of this token in the
7373 /// [`fuchsia.sysmem2/Node`] heirarchy.
7374 ///
7375 /// This method can be used to add a participant, by transferring the newly
7376 /// created token to another participant.
7377 ///
7378 /// This one-way message can be used instead of the two-way
7379 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] FIDL call in
7380 /// performance sensitive cases where it would be undesireable to wait for
7381 /// sysmem to respond to
7382 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] or when the
7383 /// client code isn't structured to make it easy to duplicate all the needed
7384 /// tokens at once.
7385 ///
7386 /// After sending one or more `Duplicate` messages, and before sending the
7387 /// newly created child tokens to other participants (or to other
7388 /// [`fuchsia.sysmem2/Allocator`] channels), the client must send a
7389 /// [`fuchsia.sysmem2/Node.Sync`] and wait for the `Sync` response. The
7390 /// `Sync` call can be made on the token, or on the `BufferCollection`
7391 /// obtained by passing this token to `BindSharedCollection`. Either will
7392 /// ensure that the server knows about the tokens created via `Duplicate`
7393 /// before the other participant sends the token to the server via separate
7394 /// `Allocator` channel.
7395 ///
7396 /// All tokens must be turned in via
7397 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
7398 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
7399 /// successfully allocate buffers.
7400 ///
7401 /// All table fields are currently required.
7402 ///
7403 /// + request `rights_attenuation_mask` The rights bits that are zero in
7404 /// this mask will be absent in the buffer VMO rights obtainable via the
7405 /// client end of `token_request`. This allows an initiator or
7406 /// intermediary participant to attenuate the rights available to a
7407 /// delegate participant. This does not allow a participant to gain rights
7408 /// that the participant doesn't already have. The value
7409 /// `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no attenuation
7410 /// should be applied.
7411 /// + These values for rights_attenuation_mask result in no attenuation:
7412 /// + `ZX_RIGHT_SAME_RIGHTS` (preferred)
7413 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is
7414 /// computed)
7415 /// + 0 (deprecated - do not use 0 - an ERROR will go to the log)
7416 /// + request `token_request` is the server end of a `BufferCollectionToken`
7417 /// channel. The client end of this channel acts as another participant in
7418 /// the shared buffer collection.
7419 pub fn r#duplicate(
7420 &self,
7421 mut payload: BufferCollectionTokenDuplicateRequest,
7422 ) -> Result<(), fidl::Error> {
7423 BufferCollectionTokenProxyInterface::r#duplicate(self, payload)
7424 }
7425
7426 /// Set this [`fuchsia.sysmem2/BufferCollectionToken`] to dispensable.
7427 ///
7428 /// When the `BufferCollectionToken` is converted to a
7429 /// [`fuchsia.sysmem2/BufferCollection`], the dispensable status applies to
7430 /// the `BufferCollection` also.
7431 ///
7432 /// Normally, if a client closes a [`fuchsia.sysmem2/BufferCollection`]
7433 /// client end without having sent
7434 /// [`fuchsia.sysmem2/BufferCollection.Release`] first, the
7435 /// `BufferCollection` [`fuchisa.sysmem2/Node`] will fail, which also
7436 /// propagates failure to the parent [`fuchsia.sysmem2/Node`] and so on up
7437 /// to the root `Node`, which fails the whole buffer collection. In
7438 /// contrast, a dispensable `Node` can fail after buffers are allocated
7439 /// without causing failure of its parent in the [`fuchsia.sysmem2/Node`]
7440 /// heirarchy.
7441 ///
7442 /// The dispensable `Node` participates in constraints aggregation along
7443 /// with its parent before buffer allocation. If the dispensable `Node`
7444 /// fails before buffers are allocated, the failure propagates to the
7445 /// dispensable `Node`'s parent.
7446 ///
7447 /// After buffers are allocated, failure of the dispensable `Node` (or any
7448 /// child of the dispensable `Node`) does not propagate to the dispensable
7449 /// `Node`'s parent. Failure does propagate from a normal child of a
7450 /// dispensable `Node` to the dispensable `Node`. Failure of a child is
7451 /// blocked from reaching its parent if the child is attached using
7452 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or if the child is
7453 /// dispensable and the failure occurred after allocation.
7454 ///
7455 /// A dispensable `Node` can be used in cases where a participant needs to
7456 /// provide constraints, but after buffers are allocated, the participant
7457 /// can fail without causing buffer collection failure from the parent
7458 /// `Node`'s point of view.
7459 ///
7460 /// In contrast, `BufferCollection.AttachToken` can be used to create a
7461 /// `BufferCollectionToken` which does not participate in constraints
7462 /// aggregation with its parent `Node`, and whose failure at any time does
7463 /// not propagate to its parent `Node`, and whose potential delay providing
7464 /// constraints does not prevent the parent `Node` from completing its
7465 /// buffer allocation.
7466 ///
7467 /// An initiator (creator of the root `Node` using
7468 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`]) may in some
7469 /// scenarios choose to initially use a dispensable `Node` for a first
7470 /// instance of a participant, and then later if the first instance of that
7471 /// participant fails, a new second instance of that participant my be given
7472 /// a `BufferCollectionToken` created with `AttachToken`.
7473 ///
7474 /// Normally a client will `SetDispensable` on a `BufferCollectionToken`
7475 /// shortly before sending the dispensable `BufferCollectionToken` to a
7476 /// delegate participant. Because `SetDispensable` prevents propagation of
7477 /// child `Node` failure to parent `Node`(s), if the client was relying on
7478 /// noticing child failure via failure of the parent `Node` retained by the
7479 /// client, the client may instead need to notice failure via other means.
7480 /// If other means aren't available/convenient, the client can instead
7481 /// retain the dispensable `Node` and create a child `Node` under that to
7482 /// send to the delegate participant, retaining this `Node` in order to
7483 /// notice failure of the subtree rooted at this `Node` via this `Node`'s
7484 /// ZX_CHANNEL_PEER_CLOSED signal, and take whatever action is appropriate
7485 /// (e.g. starting a new instance of the delegate participant and handing it
7486 /// a `BufferCollectionToken` created using
7487 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or propagate failure
7488 /// and clean up in a client-specific way).
7489 ///
7490 /// While it is possible (and potentially useful) to `SetDispensable` on a
7491 /// direct child of a `BufferCollectionTokenGroup` `Node`, it isn't possible
7492 /// to later replace a failed dispensable `Node` that was a direct child of
7493 /// a `BufferCollectionTokenGroup` with a new token using `AttachToken`
7494 /// (since there's no `AttachToken` on a group). Instead, to enable
7495 /// `AttachToken` replacement in this case, create an additional
7496 /// non-dispensable token that's a direct child of the group and make the
7497 /// existing dispensable token a child of the additional token. This way,
7498 /// the additional token that is a direct child of the group has
7499 /// `BufferCollection.AttachToken` which can be used to replace the failed
7500 /// dispensable token.
7501 ///
7502 /// `SetDispensable` on an already-dispensable token is idempotent.
7503 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
7504 BufferCollectionTokenProxyInterface::r#set_dispensable(self)
7505 }
7506
7507 /// Create a logical OR among a set of tokens, called a
7508 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
7509 ///
7510 /// Most sysmem clients and many participants don't need to care about this
7511 /// message or about `BufferCollectionTokenGroup`(s). However, in some cases
7512 /// a participant wants to attempt to include one set of delegate
7513 /// participants, but if constraints don't combine successfully that way,
7514 /// fall back to a different (possibly overlapping) set of delegate
7515 /// participants, and/or fall back to a less demanding strategy (in terms of
7516 /// how strict the [`fuchisa.sysmem2/BufferCollectionConstraints`] are,
7517 /// across all involved delegate participants). In such cases, a
7518 /// `BufferCollectionTokenGroup` is useful.
7519 ///
7520 /// A `BufferCollectionTokenGroup` is used to create a 1 of N OR among N
7521 /// child [`fuchsia.sysmem2/BufferCollectionToken`](s). The child tokens
7522 /// which are not selected during aggregation will fail (close), which a
7523 /// potential participant should notice when their `BufferCollection`
7524 /// channel client endpoint sees PEER_CLOSED, allowing the participant to
7525 /// clean up the speculative usage that didn't end up happening (this is
7526 /// simimlar to a normal `BufferCollection` server end closing on failure to
7527 /// allocate a logical buffer collection or later async failure of a buffer
7528 /// collection).
7529 ///
7530 /// See comments on protocol `BufferCollectionTokenGroup`.
7531 ///
7532 /// Any `rights_attenuation_mask` or `AttachToken`/`SetDispensable` to be
7533 /// applied to the whole group can be achieved with a
7534 /// `BufferCollectionToken` for this purpose as a direct parent of the
7535 /// `BufferCollectionTokenGroup`.
7536 ///
7537 /// All table fields are currently required.
7538 ///
7539 /// + request `group_request` The server end of a
7540 /// `BufferCollectionTokenGroup` channel to be served by sysmem.
7541 pub fn r#create_buffer_collection_token_group(
7542 &self,
7543 mut payload: BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
7544 ) -> Result<(), fidl::Error> {
7545 BufferCollectionTokenProxyInterface::r#create_buffer_collection_token_group(self, payload)
7546 }
7547}
7548
7549impl BufferCollectionTokenProxyInterface for BufferCollectionTokenProxy {
7550 type SyncResponseFut =
7551 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
7552 fn r#sync(&self) -> Self::SyncResponseFut {
7553 fn _decode(
7554 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7555 ) -> Result<(), fidl::Error> {
7556 let _response = fidl::client::decode_transaction_body::<
7557 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
7558 fidl::encoding::DefaultFuchsiaResourceDialect,
7559 0x11ac2555cf575b54,
7560 >(_buf?)?
7561 .into_result::<BufferCollectionTokenMarker>("sync")?;
7562 Ok(_response)
7563 }
7564 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
7565 (),
7566 0x11ac2555cf575b54,
7567 fidl::encoding::DynamicFlags::FLEXIBLE,
7568 _decode,
7569 )
7570 }
7571
7572 fn r#release(&self) -> Result<(), fidl::Error> {
7573 self.client.send::<fidl::encoding::EmptyPayload>(
7574 (),
7575 0x6a5cae7d6d6e04c6,
7576 fidl::encoding::DynamicFlags::FLEXIBLE,
7577 )
7578 }
7579
7580 fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
7581 self.client.send::<NodeSetNameRequest>(
7582 payload,
7583 0xb41f1624f48c1e9,
7584 fidl::encoding::DynamicFlags::FLEXIBLE,
7585 )
7586 }
7587
7588 fn r#set_debug_client_info(
7589 &self,
7590 mut payload: &NodeSetDebugClientInfoRequest,
7591 ) -> Result<(), fidl::Error> {
7592 self.client.send::<NodeSetDebugClientInfoRequest>(
7593 payload,
7594 0x5cde8914608d99b1,
7595 fidl::encoding::DynamicFlags::FLEXIBLE,
7596 )
7597 }
7598
7599 fn r#set_debug_timeout_log_deadline(
7600 &self,
7601 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
7602 ) -> Result<(), fidl::Error> {
7603 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
7604 payload,
7605 0x716b0af13d5c0806,
7606 fidl::encoding::DynamicFlags::FLEXIBLE,
7607 )
7608 }
7609
7610 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7611 self.client.send::<fidl::encoding::EmptyPayload>(
7612 (),
7613 0x5209c77415b4dfad,
7614 fidl::encoding::DynamicFlags::FLEXIBLE,
7615 )
7616 }
7617
7618 type GetNodeRefResponseFut = fidl::client::QueryResponseFut<
7619 NodeGetNodeRefResponse,
7620 fidl::encoding::DefaultFuchsiaResourceDialect,
7621 >;
7622 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
7623 fn _decode(
7624 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7625 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
7626 let _response = fidl::client::decode_transaction_body::<
7627 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
7628 fidl::encoding::DefaultFuchsiaResourceDialect,
7629 0x5b3d0e51614df053,
7630 >(_buf?)?
7631 .into_result::<BufferCollectionTokenMarker>("get_node_ref")?;
7632 Ok(_response)
7633 }
7634 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
7635 (),
7636 0x5b3d0e51614df053,
7637 fidl::encoding::DynamicFlags::FLEXIBLE,
7638 _decode,
7639 )
7640 }
7641
7642 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
7643 NodeIsAlternateForResult,
7644 fidl::encoding::DefaultFuchsiaResourceDialect,
7645 >;
7646 fn r#is_alternate_for(
7647 &self,
7648 mut payload: NodeIsAlternateForRequest,
7649 ) -> Self::IsAlternateForResponseFut {
7650 fn _decode(
7651 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7652 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
7653 let _response = fidl::client::decode_transaction_body::<
7654 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
7655 fidl::encoding::DefaultFuchsiaResourceDialect,
7656 0x3a58e00157e0825,
7657 >(_buf?)?
7658 .into_result::<BufferCollectionTokenMarker>("is_alternate_for")?;
7659 Ok(_response.map(|x| x))
7660 }
7661 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
7662 &mut payload,
7663 0x3a58e00157e0825,
7664 fidl::encoding::DynamicFlags::FLEXIBLE,
7665 _decode,
7666 )
7667 }
7668
7669 type GetBufferCollectionIdResponseFut = fidl::client::QueryResponseFut<
7670 NodeGetBufferCollectionIdResponse,
7671 fidl::encoding::DefaultFuchsiaResourceDialect,
7672 >;
7673 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut {
7674 fn _decode(
7675 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7676 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
7677 let _response = fidl::client::decode_transaction_body::<
7678 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
7679 fidl::encoding::DefaultFuchsiaResourceDialect,
7680 0x77d19a494b78ba8c,
7681 >(_buf?)?
7682 .into_result::<BufferCollectionTokenMarker>("get_buffer_collection_id")?;
7683 Ok(_response)
7684 }
7685 self.client.send_query_and_decode::<
7686 fidl::encoding::EmptyPayload,
7687 NodeGetBufferCollectionIdResponse,
7688 >(
7689 (),
7690 0x77d19a494b78ba8c,
7691 fidl::encoding::DynamicFlags::FLEXIBLE,
7692 _decode,
7693 )
7694 }
7695
7696 fn r#set_weak(&self) -> Result<(), fidl::Error> {
7697 self.client.send::<fidl::encoding::EmptyPayload>(
7698 (),
7699 0x22dd3ea514eeffe1,
7700 fidl::encoding::DynamicFlags::FLEXIBLE,
7701 )
7702 }
7703
7704 fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
7705 self.client.send::<NodeSetWeakOkRequest>(
7706 &mut payload,
7707 0x38a44fc4d7724be9,
7708 fidl::encoding::DynamicFlags::FLEXIBLE,
7709 )
7710 }
7711
7712 fn r#attach_node_tracking(
7713 &self,
7714 mut payload: NodeAttachNodeTrackingRequest,
7715 ) -> Result<(), fidl::Error> {
7716 self.client.send::<NodeAttachNodeTrackingRequest>(
7717 &mut payload,
7718 0x3f22f2a293d3cdac,
7719 fidl::encoding::DynamicFlags::FLEXIBLE,
7720 )
7721 }
7722
7723 type DuplicateSyncResponseFut = fidl::client::QueryResponseFut<
7724 BufferCollectionTokenDuplicateSyncResponse,
7725 fidl::encoding::DefaultFuchsiaResourceDialect,
7726 >;
7727 fn r#duplicate_sync(
7728 &self,
7729 mut payload: &BufferCollectionTokenDuplicateSyncRequest,
7730 ) -> Self::DuplicateSyncResponseFut {
7731 fn _decode(
7732 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7733 ) -> Result<BufferCollectionTokenDuplicateSyncResponse, fidl::Error> {
7734 let _response = fidl::client::decode_transaction_body::<
7735 fidl::encoding::FlexibleType<BufferCollectionTokenDuplicateSyncResponse>,
7736 fidl::encoding::DefaultFuchsiaResourceDialect,
7737 0x1c1af9919d1ca45c,
7738 >(_buf?)?
7739 .into_result::<BufferCollectionTokenMarker>("duplicate_sync")?;
7740 Ok(_response)
7741 }
7742 self.client.send_query_and_decode::<
7743 BufferCollectionTokenDuplicateSyncRequest,
7744 BufferCollectionTokenDuplicateSyncResponse,
7745 >(
7746 payload,
7747 0x1c1af9919d1ca45c,
7748 fidl::encoding::DynamicFlags::FLEXIBLE,
7749 _decode,
7750 )
7751 }
7752
7753 fn r#duplicate(
7754 &self,
7755 mut payload: BufferCollectionTokenDuplicateRequest,
7756 ) -> Result<(), fidl::Error> {
7757 self.client.send::<BufferCollectionTokenDuplicateRequest>(
7758 &mut payload,
7759 0x73e78f92ee7fb887,
7760 fidl::encoding::DynamicFlags::FLEXIBLE,
7761 )
7762 }
7763
7764 fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
7765 self.client.send::<fidl::encoding::EmptyPayload>(
7766 (),
7767 0x228acf979254df8b,
7768 fidl::encoding::DynamicFlags::FLEXIBLE,
7769 )
7770 }
7771
7772 fn r#create_buffer_collection_token_group(
7773 &self,
7774 mut payload: BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
7775 ) -> Result<(), fidl::Error> {
7776 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
7777 &mut payload,
7778 0x30f8d48e77bd36f2,
7779 fidl::encoding::DynamicFlags::FLEXIBLE,
7780 )
7781 }
7782}
7783
7784pub struct BufferCollectionTokenEventStream {
7785 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
7786}
7787
7788impl std::marker::Unpin for BufferCollectionTokenEventStream {}
7789
7790impl futures::stream::FusedStream for BufferCollectionTokenEventStream {
7791 fn is_terminated(&self) -> bool {
7792 self.event_receiver.is_terminated()
7793 }
7794}
7795
7796impl futures::Stream for BufferCollectionTokenEventStream {
7797 type Item = Result<BufferCollectionTokenEvent, fidl::Error>;
7798
7799 fn poll_next(
7800 mut self: std::pin::Pin<&mut Self>,
7801 cx: &mut std::task::Context<'_>,
7802 ) -> std::task::Poll<Option<Self::Item>> {
7803 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
7804 &mut self.event_receiver,
7805 cx
7806 )?) {
7807 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenEvent::decode(buf))),
7808 None => std::task::Poll::Ready(None),
7809 }
7810 }
7811}
7812
7813#[derive(Debug)]
7814pub enum BufferCollectionTokenEvent {
7815 #[non_exhaustive]
7816 _UnknownEvent {
7817 /// Ordinal of the event that was sent.
7818 ordinal: u64,
7819 },
7820}
7821
7822impl BufferCollectionTokenEvent {
7823 /// Decodes a message buffer as a [`BufferCollectionTokenEvent`].
7824 fn decode(
7825 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
7826 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
7827 let (bytes, _handles) = buf.split_mut();
7828 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7829 debug_assert_eq!(tx_header.tx_id, 0);
7830 match tx_header.ordinal {
7831 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
7832 Ok(BufferCollectionTokenEvent::_UnknownEvent { ordinal: tx_header.ordinal })
7833 }
7834 _ => Err(fidl::Error::UnknownOrdinal {
7835 ordinal: tx_header.ordinal,
7836 protocol_name:
7837 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
7838 }),
7839 }
7840 }
7841}
7842
7843/// A Stream of incoming requests for fuchsia.sysmem2/BufferCollectionToken.
7844pub struct BufferCollectionTokenRequestStream {
7845 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7846 is_terminated: bool,
7847}
7848
7849impl std::marker::Unpin for BufferCollectionTokenRequestStream {}
7850
7851impl futures::stream::FusedStream for BufferCollectionTokenRequestStream {
7852 fn is_terminated(&self) -> bool {
7853 self.is_terminated
7854 }
7855}
7856
7857impl fidl::endpoints::RequestStream for BufferCollectionTokenRequestStream {
7858 type Protocol = BufferCollectionTokenMarker;
7859 type ControlHandle = BufferCollectionTokenControlHandle;
7860
7861 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
7862 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
7863 }
7864
7865 fn control_handle(&self) -> Self::ControlHandle {
7866 BufferCollectionTokenControlHandle { inner: self.inner.clone() }
7867 }
7868
7869 fn into_inner(
7870 self,
7871 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
7872 {
7873 (self.inner, self.is_terminated)
7874 }
7875
7876 fn from_inner(
7877 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7878 is_terminated: bool,
7879 ) -> Self {
7880 Self { inner, is_terminated }
7881 }
7882}
7883
7884impl futures::Stream for BufferCollectionTokenRequestStream {
7885 type Item = Result<BufferCollectionTokenRequest, fidl::Error>;
7886
7887 fn poll_next(
7888 mut self: std::pin::Pin<&mut Self>,
7889 cx: &mut std::task::Context<'_>,
7890 ) -> std::task::Poll<Option<Self::Item>> {
7891 let this = &mut *self;
7892 if this.inner.check_shutdown(cx) {
7893 this.is_terminated = true;
7894 return std::task::Poll::Ready(None);
7895 }
7896 if this.is_terminated {
7897 panic!("polled BufferCollectionTokenRequestStream after completion");
7898 }
7899 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
7900 |bytes, handles| {
7901 match this.inner.channel().read_etc(cx, bytes, handles) {
7902 std::task::Poll::Ready(Ok(())) => {}
7903 std::task::Poll::Pending => return std::task::Poll::Pending,
7904 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
7905 this.is_terminated = true;
7906 return std::task::Poll::Ready(None);
7907 }
7908 std::task::Poll::Ready(Err(e)) => {
7909 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
7910 e.into(),
7911 ))));
7912 }
7913 }
7914
7915 // A message has been received from the channel
7916 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7917
7918 std::task::Poll::Ready(Some(match header.ordinal {
7919 0x11ac2555cf575b54 => {
7920 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7921 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7922 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7923 let control_handle = BufferCollectionTokenControlHandle {
7924 inner: this.inner.clone(),
7925 };
7926 Ok(BufferCollectionTokenRequest::Sync {
7927 responder: BufferCollectionTokenSyncResponder {
7928 control_handle: std::mem::ManuallyDrop::new(control_handle),
7929 tx_id: header.tx_id,
7930 },
7931 })
7932 }
7933 0x6a5cae7d6d6e04c6 => {
7934 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7935 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7936 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7937 let control_handle = BufferCollectionTokenControlHandle {
7938 inner: this.inner.clone(),
7939 };
7940 Ok(BufferCollectionTokenRequest::Release {
7941 control_handle,
7942 })
7943 }
7944 0xb41f1624f48c1e9 => {
7945 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7946 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7947 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
7948 let control_handle = BufferCollectionTokenControlHandle {
7949 inner: this.inner.clone(),
7950 };
7951 Ok(BufferCollectionTokenRequest::SetName {payload: req,
7952 control_handle,
7953 })
7954 }
7955 0x5cde8914608d99b1 => {
7956 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7957 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7958 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
7959 let control_handle = BufferCollectionTokenControlHandle {
7960 inner: this.inner.clone(),
7961 };
7962 Ok(BufferCollectionTokenRequest::SetDebugClientInfo {payload: req,
7963 control_handle,
7964 })
7965 }
7966 0x716b0af13d5c0806 => {
7967 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7968 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7969 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
7970 let control_handle = BufferCollectionTokenControlHandle {
7971 inner: this.inner.clone(),
7972 };
7973 Ok(BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {payload: req,
7974 control_handle,
7975 })
7976 }
7977 0x5209c77415b4dfad => {
7978 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7979 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7980 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7981 let control_handle = BufferCollectionTokenControlHandle {
7982 inner: this.inner.clone(),
7983 };
7984 Ok(BufferCollectionTokenRequest::SetVerboseLogging {
7985 control_handle,
7986 })
7987 }
7988 0x5b3d0e51614df053 => {
7989 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7990 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7991 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7992 let control_handle = BufferCollectionTokenControlHandle {
7993 inner: this.inner.clone(),
7994 };
7995 Ok(BufferCollectionTokenRequest::GetNodeRef {
7996 responder: BufferCollectionTokenGetNodeRefResponder {
7997 control_handle: std::mem::ManuallyDrop::new(control_handle),
7998 tx_id: header.tx_id,
7999 },
8000 })
8001 }
8002 0x3a58e00157e0825 => {
8003 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
8004 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8005 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
8006 let control_handle = BufferCollectionTokenControlHandle {
8007 inner: this.inner.clone(),
8008 };
8009 Ok(BufferCollectionTokenRequest::IsAlternateFor {payload: req,
8010 responder: BufferCollectionTokenIsAlternateForResponder {
8011 control_handle: std::mem::ManuallyDrop::new(control_handle),
8012 tx_id: header.tx_id,
8013 },
8014 })
8015 }
8016 0x77d19a494b78ba8c => {
8017 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
8018 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
8019 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
8020 let control_handle = BufferCollectionTokenControlHandle {
8021 inner: this.inner.clone(),
8022 };
8023 Ok(BufferCollectionTokenRequest::GetBufferCollectionId {
8024 responder: BufferCollectionTokenGetBufferCollectionIdResponder {
8025 control_handle: std::mem::ManuallyDrop::new(control_handle),
8026 tx_id: header.tx_id,
8027 },
8028 })
8029 }
8030 0x22dd3ea514eeffe1 => {
8031 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8032 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
8033 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
8034 let control_handle = BufferCollectionTokenControlHandle {
8035 inner: this.inner.clone(),
8036 };
8037 Ok(BufferCollectionTokenRequest::SetWeak {
8038 control_handle,
8039 })
8040 }
8041 0x38a44fc4d7724be9 => {
8042 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8043 let mut req = fidl::new_empty!(NodeSetWeakOkRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8044 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetWeakOkRequest>(&header, _body_bytes, handles, &mut req)?;
8045 let control_handle = BufferCollectionTokenControlHandle {
8046 inner: this.inner.clone(),
8047 };
8048 Ok(BufferCollectionTokenRequest::SetWeakOk {payload: req,
8049 control_handle,
8050 })
8051 }
8052 0x3f22f2a293d3cdac => {
8053 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8054 let mut req = fidl::new_empty!(NodeAttachNodeTrackingRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8055 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeAttachNodeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
8056 let control_handle = BufferCollectionTokenControlHandle {
8057 inner: this.inner.clone(),
8058 };
8059 Ok(BufferCollectionTokenRequest::AttachNodeTracking {payload: req,
8060 control_handle,
8061 })
8062 }
8063 0x1c1af9919d1ca45c => {
8064 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
8065 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8066 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateSyncRequest>(&header, _body_bytes, handles, &mut req)?;
8067 let control_handle = BufferCollectionTokenControlHandle {
8068 inner: this.inner.clone(),
8069 };
8070 Ok(BufferCollectionTokenRequest::DuplicateSync {payload: req,
8071 responder: BufferCollectionTokenDuplicateSyncResponder {
8072 control_handle: std::mem::ManuallyDrop::new(control_handle),
8073 tx_id: header.tx_id,
8074 },
8075 })
8076 }
8077 0x73e78f92ee7fb887 => {
8078 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8079 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8080 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateRequest>(&header, _body_bytes, handles, &mut req)?;
8081 let control_handle = BufferCollectionTokenControlHandle {
8082 inner: this.inner.clone(),
8083 };
8084 Ok(BufferCollectionTokenRequest::Duplicate {payload: req,
8085 control_handle,
8086 })
8087 }
8088 0x228acf979254df8b => {
8089 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8090 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
8091 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
8092 let control_handle = BufferCollectionTokenControlHandle {
8093 inner: this.inner.clone(),
8094 };
8095 Ok(BufferCollectionTokenRequest::SetDispensable {
8096 control_handle,
8097 })
8098 }
8099 0x30f8d48e77bd36f2 => {
8100 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
8101 let mut req = fidl::new_empty!(BufferCollectionTokenCreateBufferCollectionTokenGroupRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
8102 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(&header, _body_bytes, handles, &mut req)?;
8103 let control_handle = BufferCollectionTokenControlHandle {
8104 inner: this.inner.clone(),
8105 };
8106 Ok(BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {payload: req,
8107 control_handle,
8108 })
8109 }
8110 _ if header.tx_id == 0 && header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
8111 Ok(BufferCollectionTokenRequest::_UnknownMethod {
8112 ordinal: header.ordinal,
8113 control_handle: BufferCollectionTokenControlHandle { inner: this.inner.clone() },
8114 method_type: fidl::MethodType::OneWay,
8115 })
8116 }
8117 _ if header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
8118 this.inner.send_framework_err(
8119 fidl::encoding::FrameworkErr::UnknownMethod,
8120 header.tx_id,
8121 header.ordinal,
8122 header.dynamic_flags(),
8123 (bytes, handles),
8124 )?;
8125 Ok(BufferCollectionTokenRequest::_UnknownMethod {
8126 ordinal: header.ordinal,
8127 control_handle: BufferCollectionTokenControlHandle { inner: this.inner.clone() },
8128 method_type: fidl::MethodType::TwoWay,
8129 })
8130 }
8131 _ => Err(fidl::Error::UnknownOrdinal {
8132 ordinal: header.ordinal,
8133 protocol_name: <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
8134 }),
8135 }))
8136 },
8137 )
8138 }
8139}
8140
8141/// A [`fuchsia.sysmem2/BufferCollectionToken`] is not a buffer collection, but
8142/// rather is a way to identify a specific potential shared buffer collection,
8143/// and a way to distribute that potential shared buffer collection to
8144/// additional participants prior to the buffer collection allocating any
8145/// buffers.
8146///
8147/// Epitaphs are not used in this protocol.
8148///
8149/// We use a channel for the `BufferCollectionToken` instead of a single
8150/// `eventpair` (pair) because this way we can detect error conditions like a
8151/// participant failing mid-create.
8152#[derive(Debug)]
8153pub enum BufferCollectionTokenRequest {
8154 /// Ensure that previous messages have been received server side. This is
8155 /// particularly useful after previous messages that created new tokens,
8156 /// because a token must be known to the sysmem server before sending the
8157 /// token to another participant.
8158 ///
8159 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
8160 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
8161 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
8162 /// to mitigate the possibility of a hostile/fake
8163 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
8164 /// Another way is to pass the token to
8165 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
8166 /// the token as part of exchanging it for a
8167 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
8168 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
8169 /// of stalling.
8170 ///
8171 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
8172 /// and then starting and completing a `Sync`, it's then safe to send the
8173 /// `BufferCollectionToken` client ends to other participants knowing the
8174 /// server will recognize the tokens when they're sent by the other
8175 /// participants to sysmem in a
8176 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
8177 /// efficient way to create tokens while avoiding unnecessary round trips.
8178 ///
8179 /// Other options include waiting for each
8180 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
8181 /// individually (using separate call to `Sync` after each), or calling
8182 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
8183 /// converted to a `BufferCollection` via
8184 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
8185 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
8186 /// the sync step and can create multiple tokens at once.
8187 Sync { responder: BufferCollectionTokenSyncResponder },
8188 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
8189 ///
8190 /// Normally a participant will convert a `BufferCollectionToken` into a
8191 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
8192 /// `Release` via the token (and then close the channel immediately or
8193 /// shortly later in response to server closing the server end), which
8194 /// avoids causing buffer collection failure. Without a prior `Release`,
8195 /// closing the `BufferCollectionToken` client end will cause buffer
8196 /// collection failure.
8197 ///
8198 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
8199 ///
8200 /// By default the server handles unexpected closure of a
8201 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
8202 /// first) by failing the buffer collection. Partly this is to expedite
8203 /// closing VMO handles to reclaim memory when any participant fails. If a
8204 /// participant would like to cleanly close a `BufferCollection` without
8205 /// causing buffer collection failure, the participant can send `Release`
8206 /// before closing the `BufferCollection` client end. The `Release` can
8207 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
8208 /// buffer collection won't require constraints from this node in order to
8209 /// allocate. If after `SetConstraints`, the constraints are retained and
8210 /// aggregated, despite the lack of `BufferCollection` connection at the
8211 /// time of constraints aggregation.
8212 ///
8213 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
8214 ///
8215 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
8216 /// end (without `Release` first) will trigger failure of the buffer
8217 /// collection. To close a `BufferCollectionTokenGroup` channel without
8218 /// failing the buffer collection, ensure that AllChildrenPresent() has been
8219 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
8220 /// client end.
8221 ///
8222 /// If `Release` occurs before
8223 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
8224 /// buffer collection will fail (triggered by reception of `Release` without
8225 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
8226 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
8227 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
8228 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
8229 /// close requires `AllChildrenPresent` (if not already sent), then
8230 /// `Release`, then close client end.
8231 ///
8232 /// If `Release` occurs after `AllChildrenPresent`, the children and all
8233 /// their constraints remain intact (just as they would if the
8234 /// `BufferCollectionTokenGroup` channel had remained open), and the client
8235 /// end close doesn't trigger buffer collection failure.
8236 ///
8237 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
8238 ///
8239 /// For brevity, the per-channel-protocol paragraphs above ignore the
8240 /// separate failure domain created by
8241 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
8242 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
8243 /// unexpectedly closes (without `Release` first) and that client end is
8244 /// under a failure domain, instead of failing the whole buffer collection,
8245 /// the failure domain is failed, but the buffer collection itself is
8246 /// isolated from failure of the failure domain. Such failure domains can be
8247 /// nested, in which case only the inner-most failure domain in which the
8248 /// `Node` resides fails.
8249 Release { control_handle: BufferCollectionTokenControlHandle },
8250 /// Set a name for VMOs in this buffer collection.
8251 ///
8252 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
8253 /// will be truncated to fit. The name of the vmo will be suffixed with the
8254 /// buffer index within the collection (if the suffix fits within
8255 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
8256 /// listed in the inspect data.
8257 ///
8258 /// The name only affects VMOs allocated after the name is set; this call
8259 /// does not rename existing VMOs. If multiple clients set different names
8260 /// then the larger priority value will win. Setting a new name with the
8261 /// same priority as a prior name doesn't change the name.
8262 ///
8263 /// All table fields are currently required.
8264 ///
8265 /// + request `priority` The name is only set if this is the first `SetName`
8266 /// or if `priority` is greater than any previous `priority` value in
8267 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
8268 /// + request `name` The name for VMOs created under this buffer collection.
8269 SetName { payload: NodeSetNameRequest, control_handle: BufferCollectionTokenControlHandle },
8270 /// Set information about the current client that can be used by sysmem to
8271 /// help diagnose leaking memory and allocation stalls waiting for a
8272 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
8273 ///
8274 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
8275 /// `Node`(s) derived from this `Node`, unless overriden by
8276 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
8277 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
8278 ///
8279 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
8280 /// `Allocator` is the most efficient way to ensure that all
8281 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
8282 /// set, and is also more efficient than separately sending the same debug
8283 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
8284 /// created [`fuchsia.sysmem2/Node`].
8285 ///
8286 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
8287 /// indicate which client is closing their channel first, leading to subtree
8288 /// failure (which can be normal if the purpose of the subtree is over, but
8289 /// if happening earlier than expected, the client-channel-specific name can
8290 /// help diagnose where the failure is first coming from, from sysmem's
8291 /// point of view).
8292 ///
8293 /// All table fields are currently required.
8294 ///
8295 /// + request `name` This can be an arbitrary string, but the current
8296 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
8297 /// + request `id` This can be an arbitrary id, but the current process ID
8298 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
8299 SetDebugClientInfo {
8300 payload: NodeSetDebugClientInfoRequest,
8301 control_handle: BufferCollectionTokenControlHandle,
8302 },
8303 /// Sysmem logs a warning if sysmem hasn't seen
8304 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
8305 /// within 5 seconds after creation of a new collection.
8306 ///
8307 /// Clients can call this method to change when the log is printed. If
8308 /// multiple client set the deadline, it's unspecified which deadline will
8309 /// take effect.
8310 ///
8311 /// In most cases the default works well.
8312 ///
8313 /// All table fields are currently required.
8314 ///
8315 /// + request `deadline` The time at which sysmem will start trying to log
8316 /// the warning, unless all constraints are with sysmem by then.
8317 SetDebugTimeoutLogDeadline {
8318 payload: NodeSetDebugTimeoutLogDeadlineRequest,
8319 control_handle: BufferCollectionTokenControlHandle,
8320 },
8321 /// This enables verbose logging for the buffer collection.
8322 ///
8323 /// Verbose logging includes constraints set via
8324 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
8325 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
8326 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
8327 /// the tree of `Node`(s).
8328 ///
8329 /// Normally sysmem prints only a single line complaint when aggregation
8330 /// fails, with just the specific detailed reason that aggregation failed,
8331 /// with little surrounding context. While this is often enough to diagnose
8332 /// a problem if only a small change was made and everything was working
8333 /// before the small change, it's often not particularly helpful for getting
8334 /// a new buffer collection to work for the first time. Especially with
8335 /// more complex trees of nodes, involving things like
8336 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
8337 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
8338 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
8339 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
8340 /// looks like and why it's failing a logical allocation, or why a tree or
8341 /// subtree is failing sooner than expected.
8342 ///
8343 /// The intent of the extra logging is to be acceptable from a performance
8344 /// point of view, under the assumption that verbose logging is only enabled
8345 /// on a low number of buffer collections. If we're not tracking down a bug,
8346 /// we shouldn't send this message.
8347 SetVerboseLogging { control_handle: BufferCollectionTokenControlHandle },
8348 /// This gets a handle that can be used as a parameter to
8349 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
8350 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
8351 /// client obtained this handle from this `Node`.
8352 ///
8353 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
8354 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
8355 /// despite the two calls typically being on different channels.
8356 ///
8357 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
8358 ///
8359 /// All table fields are currently required.
8360 ///
8361 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
8362 /// different `Node` channel, to prove that the client obtained the handle
8363 /// from this `Node`.
8364 GetNodeRef { responder: BufferCollectionTokenGetNodeRefResponder },
8365 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
8366 /// rooted at a different child token of a common parent
8367 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
8368 /// passed-in `node_ref`.
8369 ///
8370 /// This call is for assisting with admission control de-duplication, and
8371 /// with debugging.
8372 ///
8373 /// The `node_ref` must be obtained using
8374 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
8375 ///
8376 /// The `node_ref` can be a duplicated handle; it's not necessary to call
8377 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
8378 ///
8379 /// If a calling token may not actually be a valid token at all due to a
8380 /// potentially hostile/untrusted provider of the token, call
8381 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
8382 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
8383 /// never responds due to a calling token not being a real token (not really
8384 /// talking to sysmem). Another option is to call
8385 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
8386 /// which also validates the token along with converting it to a
8387 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
8388 ///
8389 /// All table fields are currently required.
8390 ///
8391 /// - response `is_alternate`
8392 /// - true: The first parent node in common between the calling node and
8393 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
8394 /// that the calling `Node` and the `node_ref` `Node` will not have both
8395 /// their constraints apply - rather sysmem will choose one or the other
8396 /// of the constraints - never both. This is because only one child of
8397 /// a `BufferCollectionTokenGroup` is selected during logical
8398 /// allocation, with only that one child's subtree contributing to
8399 /// constraints aggregation.
8400 /// - false: The first parent node in common between the calling `Node`
8401 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
8402 /// Currently, this means the first parent node in common is a
8403 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
8404 /// `Release`ed). This means that the calling `Node` and the `node_ref`
8405 /// `Node` may have both their constraints apply during constraints
8406 /// aggregation of the logical allocation, if both `Node`(s) are
8407 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
8408 /// this case, there is no `BufferCollectionTokenGroup` that will
8409 /// directly prevent the two `Node`(s) from both being selected and
8410 /// their constraints both aggregated, but even when false, one or both
8411 /// `Node`(s) may still be eliminated from consideration if one or both
8412 /// `Node`(s) has a direct or indirect parent
8413 /// `BufferCollectionTokenGroup` which selects a child subtree other
8414 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
8415 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
8416 /// associated with the same buffer collection as the calling `Node`.
8417 /// Another reason for this error is if the `node_ref` is an
8418 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
8419 /// a real `node_ref` obtained from `GetNodeRef`.
8420 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
8421 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
8422 /// the needed rights expected on a real `node_ref`.
8423 /// * No other failing status codes are returned by this call. However,
8424 /// sysmem may add additional codes in future, so the client should have
8425 /// sensible default handling for any failing status code.
8426 IsAlternateFor {
8427 payload: NodeIsAlternateForRequest,
8428 responder: BufferCollectionTokenIsAlternateForResponder,
8429 },
8430 /// Get the buffer collection ID. This ID is also available from
8431 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
8432 /// within the collection).
8433 ///
8434 /// This call is mainly useful in situations where we can't convey a
8435 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
8436 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
8437 /// handle, which can be joined back up with a `BufferCollection` client end
8438 /// that was created via a different path. Prefer to convey a
8439 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
8440 ///
8441 /// Trusting a `buffer_collection_id` value from a source other than sysmem
8442 /// is analogous to trusting a koid value from a source other than zircon.
8443 /// Both should be avoided unless really necessary, and both require
8444 /// caution. In some situations it may be reasonable to refer to a
8445 /// pre-established `BufferCollection` by `buffer_collection_id` via a
8446 /// protocol for efficiency reasons, but an incoming value purporting to be
8447 /// a `buffer_collection_id` is not sufficient alone to justify granting the
8448 /// sender of the `buffer_collection_id` any capability. The sender must
8449 /// first prove to a receiver that the sender has/had a VMO or has/had a
8450 /// `BufferCollectionToken` to the same collection by sending a handle that
8451 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
8452 /// `buffer_collection_id` value. The receiver should take care to avoid
8453 /// assuming that a sender had a `BufferCollectionToken` in cases where the
8454 /// sender has only proven that the sender had a VMO.
8455 ///
8456 /// - response `buffer_collection_id` This ID is unique per buffer
8457 /// collection per boot. Each buffer is uniquely identified by the
8458 /// `buffer_collection_id` and `buffer_index` together.
8459 GetBufferCollectionId { responder: BufferCollectionTokenGetBufferCollectionIdResponder },
8460 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
8461 /// created after this message to weak, which means that a client's `Node`
8462 /// client end (or a child created after this message) is not alone
8463 /// sufficient to keep allocated VMOs alive.
8464 ///
8465 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
8466 /// `close_weak_asap`.
8467 ///
8468 /// This message is only permitted before the `Node` becomes ready for
8469 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
8470 /// * `BufferCollectionToken`: any time
8471 /// * `BufferCollection`: before `SetConstraints`
8472 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
8473 ///
8474 /// Currently, no conversion from strong `Node` to weak `Node` after ready
8475 /// for allocation is provided, but a client can simulate that by creating
8476 /// an additional `Node` before allocation and setting that additional
8477 /// `Node` to weak, and then potentially at some point later sending
8478 /// `Release` and closing the client end of the client's strong `Node`, but
8479 /// keeping the client's weak `Node`.
8480 ///
8481 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
8482 /// collection failure (all `Node` client end(s) will see
8483 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
8484 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
8485 /// this situation until all `Node`(s) are ready for allocation. For initial
8486 /// allocation to succeed, at least one strong `Node` is required to exist
8487 /// at allocation time, but after that client receives VMO handles, that
8488 /// client can `BufferCollection.Release` and close the client end without
8489 /// causing this type of failure.
8490 ///
8491 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
8492 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
8493 /// separately as appropriate.
8494 SetWeak { control_handle: BufferCollectionTokenControlHandle },
8495 /// This indicates to sysmem that the client is prepared to pay attention to
8496 /// `close_weak_asap`.
8497 ///
8498 /// If sent, this message must be before
8499 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
8500 ///
8501 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
8502 /// send this message before `WaitForAllBuffersAllocated`, or a parent
8503 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
8504 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
8505 /// trigger buffer collection failure.
8506 ///
8507 /// This message is necessary because weak sysmem VMOs have not always been
8508 /// a thing, so older clients are not aware of the need to pay attention to
8509 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
8510 /// sysmem weak VMO handles asap. By having this message and requiring
8511 /// participants to indicate their acceptance of this aspect of the overall
8512 /// protocol, we avoid situations where an older client is delivered a weak
8513 /// VMO without any way for sysmem to get that VMO to close quickly later
8514 /// (and on a per-buffer basis).
8515 ///
8516 /// A participant that doesn't handle `close_weak_asap` and also doesn't
8517 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
8518 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
8519 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
8520 /// same participant has a child/delegate which does retrieve VMOs, that
8521 /// child/delegate will need to send `SetWeakOk` before
8522 /// `WaitForAllBuffersAllocated`.
8523 ///
8524 /// + request `for_child_nodes_also` If present and true, this means direct
8525 /// child nodes of this node created after this message plus all
8526 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
8527 /// those nodes. Any child node of this node that was created before this
8528 /// message is not included. This setting is "sticky" in the sense that a
8529 /// subsequent `SetWeakOk` without this bool set to true does not reset
8530 /// the server-side bool. If this creates a problem for a participant, a
8531 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
8532 /// tokens instead, as appropriate. A participant should only set
8533 /// `for_child_nodes_also` true if the participant can really promise to
8534 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
8535 /// weak VMO handles held by participants holding the corresponding child
8536 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
8537 /// which are using sysmem(1) can be weak, despite the clients of those
8538 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
8539 /// direct way to find out about `close_weak_asap`. This only applies to
8540 /// descendents of this `Node` which are using sysmem(1), not to this
8541 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
8542 /// token, which will fail allocation unless an ancestor of this `Node`
8543 /// specified `for_child_nodes_also` true.
8544 SetWeakOk { payload: NodeSetWeakOkRequest, control_handle: BufferCollectionTokenControlHandle },
8545 /// The server_end will be closed after this `Node` and any child nodes have
8546 /// have released their buffer counts, making those counts available for
8547 /// reservation by a different `Node` via
8548 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
8549 ///
8550 /// The `Node` buffer counts may not be released until the entire tree of
8551 /// `Node`(s) is closed or failed, because
8552 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
8553 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
8554 /// `Node` buffer counts remain reserved until the orphaned node is later
8555 /// cleaned up.
8556 ///
8557 /// If the `Node` exceeds a fairly large number of attached eventpair server
8558 /// ends, a log message will indicate this and the `Node` (and the
8559 /// appropriate) sub-tree will fail.
8560 ///
8561 /// The `server_end` will remain open when
8562 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
8563 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
8564 /// [`fuchsia.sysmem2/BufferCollection`].
8565 ///
8566 /// This message can also be used with a
8567 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
8568 AttachNodeTracking {
8569 payload: NodeAttachNodeTrackingRequest,
8570 control_handle: BufferCollectionTokenControlHandle,
8571 },
8572 /// Create additional [`fuchsia.sysmem2/BufferCollectionToken`](s) from this
8573 /// one, referring to the same buffer collection.
8574 ///
8575 /// The created tokens are children of this token in the
8576 /// [`fuchsia.sysmem2/Node`] heirarchy.
8577 ///
8578 /// This method can be used to add more participants, by transferring the
8579 /// newly created tokens to additional participants.
8580 ///
8581 /// A new token will be returned for each entry in the
8582 /// `rights_attenuation_masks` array.
8583 ///
8584 /// If the called token may not actually be a valid token due to a
8585 /// potentially hostile/untrusted provider of the token, consider using
8586 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
8587 /// instead of potentially getting stuck indefinitely if
8588 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] never responds
8589 /// due to the calling token not being a real token.
8590 ///
8591 /// In contrast to [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`], no
8592 /// separate [`fuchsia.sysmem2/Node.Sync`] is needed after calling this
8593 /// method, because the sync step is included in this call, at the cost of a
8594 /// round trip during this call.
8595 ///
8596 /// All tokens must be turned in to sysmem via
8597 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
8598 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
8599 /// successfully allocate buffers (or to logically allocate buffers in the
8600 /// case of subtrees involving
8601 /// [`fuchsia.sysmem2/BufferCollectionToken.AttachToken`]).
8602 ///
8603 /// All table fields are currently required.
8604 ///
8605 /// + request `rights_attenuation_mask` In each entry of
8606 /// `rights_attenuation_masks`, rights bits that are zero will be absent
8607 /// in the buffer VMO rights obtainable via the corresponding returned
8608 /// token. This allows an initiator or intermediary participant to
8609 /// attenuate the rights available to a participant. This does not allow a
8610 /// participant to gain rights that the participant doesn't already have.
8611 /// The value `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no
8612 /// attenuation should be applied.
8613 /// - response `tokens` The client ends of each newly created token.
8614 DuplicateSync {
8615 payload: BufferCollectionTokenDuplicateSyncRequest,
8616 responder: BufferCollectionTokenDuplicateSyncResponder,
8617 },
8618 /// Create an additional [`fuchsia.sysmem2/BufferCollectionToken`] from this
8619 /// one, referring to the same buffer collection.
8620 ///
8621 /// The created token is a child of this token in the
8622 /// [`fuchsia.sysmem2/Node`] heirarchy.
8623 ///
8624 /// This method can be used to add a participant, by transferring the newly
8625 /// created token to another participant.
8626 ///
8627 /// This one-way message can be used instead of the two-way
8628 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] FIDL call in
8629 /// performance sensitive cases where it would be undesireable to wait for
8630 /// sysmem to respond to
8631 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] or when the
8632 /// client code isn't structured to make it easy to duplicate all the needed
8633 /// tokens at once.
8634 ///
8635 /// After sending one or more `Duplicate` messages, and before sending the
8636 /// newly created child tokens to other participants (or to other
8637 /// [`fuchsia.sysmem2/Allocator`] channels), the client must send a
8638 /// [`fuchsia.sysmem2/Node.Sync`] and wait for the `Sync` response. The
8639 /// `Sync` call can be made on the token, or on the `BufferCollection`
8640 /// obtained by passing this token to `BindSharedCollection`. Either will
8641 /// ensure that the server knows about the tokens created via `Duplicate`
8642 /// before the other participant sends the token to the server via separate
8643 /// `Allocator` channel.
8644 ///
8645 /// All tokens must be turned in via
8646 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] or
8647 /// [`fuchsia.sysmem2/Node.Release`] for a `BufferCollection` to
8648 /// successfully allocate buffers.
8649 ///
8650 /// All table fields are currently required.
8651 ///
8652 /// + request `rights_attenuation_mask` The rights bits that are zero in
8653 /// this mask will be absent in the buffer VMO rights obtainable via the
8654 /// client end of `token_request`. This allows an initiator or
8655 /// intermediary participant to attenuate the rights available to a
8656 /// delegate participant. This does not allow a participant to gain rights
8657 /// that the participant doesn't already have. The value
8658 /// `ZX_RIGHT_SAME_RIGHTS` can be used to specify that no attenuation
8659 /// should be applied.
8660 /// + These values for rights_attenuation_mask result in no attenuation:
8661 /// + `ZX_RIGHT_SAME_RIGHTS` (preferred)
8662 /// + 0xFFFFFFFF (this is reasonable when an attenuation mask is
8663 /// computed)
8664 /// + 0 (deprecated - do not use 0 - an ERROR will go to the log)
8665 /// + request `token_request` is the server end of a `BufferCollectionToken`
8666 /// channel. The client end of this channel acts as another participant in
8667 /// the shared buffer collection.
8668 Duplicate {
8669 payload: BufferCollectionTokenDuplicateRequest,
8670 control_handle: BufferCollectionTokenControlHandle,
8671 },
8672 /// Set this [`fuchsia.sysmem2/BufferCollectionToken`] to dispensable.
8673 ///
8674 /// When the `BufferCollectionToken` is converted to a
8675 /// [`fuchsia.sysmem2/BufferCollection`], the dispensable status applies to
8676 /// the `BufferCollection` also.
8677 ///
8678 /// Normally, if a client closes a [`fuchsia.sysmem2/BufferCollection`]
8679 /// client end without having sent
8680 /// [`fuchsia.sysmem2/BufferCollection.Release`] first, the
8681 /// `BufferCollection` [`fuchisa.sysmem2/Node`] will fail, which also
8682 /// propagates failure to the parent [`fuchsia.sysmem2/Node`] and so on up
8683 /// to the root `Node`, which fails the whole buffer collection. In
8684 /// contrast, a dispensable `Node` can fail after buffers are allocated
8685 /// without causing failure of its parent in the [`fuchsia.sysmem2/Node`]
8686 /// heirarchy.
8687 ///
8688 /// The dispensable `Node` participates in constraints aggregation along
8689 /// with its parent before buffer allocation. If the dispensable `Node`
8690 /// fails before buffers are allocated, the failure propagates to the
8691 /// dispensable `Node`'s parent.
8692 ///
8693 /// After buffers are allocated, failure of the dispensable `Node` (or any
8694 /// child of the dispensable `Node`) does not propagate to the dispensable
8695 /// `Node`'s parent. Failure does propagate from a normal child of a
8696 /// dispensable `Node` to the dispensable `Node`. Failure of a child is
8697 /// blocked from reaching its parent if the child is attached using
8698 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or if the child is
8699 /// dispensable and the failure occurred after allocation.
8700 ///
8701 /// A dispensable `Node` can be used in cases where a participant needs to
8702 /// provide constraints, but after buffers are allocated, the participant
8703 /// can fail without causing buffer collection failure from the parent
8704 /// `Node`'s point of view.
8705 ///
8706 /// In contrast, `BufferCollection.AttachToken` can be used to create a
8707 /// `BufferCollectionToken` which does not participate in constraints
8708 /// aggregation with its parent `Node`, and whose failure at any time does
8709 /// not propagate to its parent `Node`, and whose potential delay providing
8710 /// constraints does not prevent the parent `Node` from completing its
8711 /// buffer allocation.
8712 ///
8713 /// An initiator (creator of the root `Node` using
8714 /// [`fuchsia.sysmem2/Allocator.AllocateSharedCollection`]) may in some
8715 /// scenarios choose to initially use a dispensable `Node` for a first
8716 /// instance of a participant, and then later if the first instance of that
8717 /// participant fails, a new second instance of that participant my be given
8718 /// a `BufferCollectionToken` created with `AttachToken`.
8719 ///
8720 /// Normally a client will `SetDispensable` on a `BufferCollectionToken`
8721 /// shortly before sending the dispensable `BufferCollectionToken` to a
8722 /// delegate participant. Because `SetDispensable` prevents propagation of
8723 /// child `Node` failure to parent `Node`(s), if the client was relying on
8724 /// noticing child failure via failure of the parent `Node` retained by the
8725 /// client, the client may instead need to notice failure via other means.
8726 /// If other means aren't available/convenient, the client can instead
8727 /// retain the dispensable `Node` and create a child `Node` under that to
8728 /// send to the delegate participant, retaining this `Node` in order to
8729 /// notice failure of the subtree rooted at this `Node` via this `Node`'s
8730 /// ZX_CHANNEL_PEER_CLOSED signal, and take whatever action is appropriate
8731 /// (e.g. starting a new instance of the delegate participant and handing it
8732 /// a `BufferCollectionToken` created using
8733 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`], or propagate failure
8734 /// and clean up in a client-specific way).
8735 ///
8736 /// While it is possible (and potentially useful) to `SetDispensable` on a
8737 /// direct child of a `BufferCollectionTokenGroup` `Node`, it isn't possible
8738 /// to later replace a failed dispensable `Node` that was a direct child of
8739 /// a `BufferCollectionTokenGroup` with a new token using `AttachToken`
8740 /// (since there's no `AttachToken` on a group). Instead, to enable
8741 /// `AttachToken` replacement in this case, create an additional
8742 /// non-dispensable token that's a direct child of the group and make the
8743 /// existing dispensable token a child of the additional token. This way,
8744 /// the additional token that is a direct child of the group has
8745 /// `BufferCollection.AttachToken` which can be used to replace the failed
8746 /// dispensable token.
8747 ///
8748 /// `SetDispensable` on an already-dispensable token is idempotent.
8749 SetDispensable { control_handle: BufferCollectionTokenControlHandle },
8750 /// Create a logical OR among a set of tokens, called a
8751 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
8752 ///
8753 /// Most sysmem clients and many participants don't need to care about this
8754 /// message or about `BufferCollectionTokenGroup`(s). However, in some cases
8755 /// a participant wants to attempt to include one set of delegate
8756 /// participants, but if constraints don't combine successfully that way,
8757 /// fall back to a different (possibly overlapping) set of delegate
8758 /// participants, and/or fall back to a less demanding strategy (in terms of
8759 /// how strict the [`fuchisa.sysmem2/BufferCollectionConstraints`] are,
8760 /// across all involved delegate participants). In such cases, a
8761 /// `BufferCollectionTokenGroup` is useful.
8762 ///
8763 /// A `BufferCollectionTokenGroup` is used to create a 1 of N OR among N
8764 /// child [`fuchsia.sysmem2/BufferCollectionToken`](s). The child tokens
8765 /// which are not selected during aggregation will fail (close), which a
8766 /// potential participant should notice when their `BufferCollection`
8767 /// channel client endpoint sees PEER_CLOSED, allowing the participant to
8768 /// clean up the speculative usage that didn't end up happening (this is
8769 /// simimlar to a normal `BufferCollection` server end closing on failure to
8770 /// allocate a logical buffer collection or later async failure of a buffer
8771 /// collection).
8772 ///
8773 /// See comments on protocol `BufferCollectionTokenGroup`.
8774 ///
8775 /// Any `rights_attenuation_mask` or `AttachToken`/`SetDispensable` to be
8776 /// applied to the whole group can be achieved with a
8777 /// `BufferCollectionToken` for this purpose as a direct parent of the
8778 /// `BufferCollectionTokenGroup`.
8779 ///
8780 /// All table fields are currently required.
8781 ///
8782 /// + request `group_request` The server end of a
8783 /// `BufferCollectionTokenGroup` channel to be served by sysmem.
8784 CreateBufferCollectionTokenGroup {
8785 payload: BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
8786 control_handle: BufferCollectionTokenControlHandle,
8787 },
8788 /// An interaction was received which does not match any known method.
8789 #[non_exhaustive]
8790 _UnknownMethod {
8791 /// Ordinal of the method that was called.
8792 ordinal: u64,
8793 control_handle: BufferCollectionTokenControlHandle,
8794 method_type: fidl::MethodType,
8795 },
8796}
8797
8798impl BufferCollectionTokenRequest {
8799 #[allow(irrefutable_let_patterns)]
8800 pub fn into_sync(self) -> Option<(BufferCollectionTokenSyncResponder)> {
8801 if let BufferCollectionTokenRequest::Sync { responder } = self {
8802 Some((responder))
8803 } else {
8804 None
8805 }
8806 }
8807
8808 #[allow(irrefutable_let_patterns)]
8809 pub fn into_release(self) -> Option<(BufferCollectionTokenControlHandle)> {
8810 if let BufferCollectionTokenRequest::Release { control_handle } = self {
8811 Some((control_handle))
8812 } else {
8813 None
8814 }
8815 }
8816
8817 #[allow(irrefutable_let_patterns)]
8818 pub fn into_set_name(self) -> Option<(NodeSetNameRequest, BufferCollectionTokenControlHandle)> {
8819 if let BufferCollectionTokenRequest::SetName { payload, control_handle } = self {
8820 Some((payload, control_handle))
8821 } else {
8822 None
8823 }
8824 }
8825
8826 #[allow(irrefutable_let_patterns)]
8827 pub fn into_set_debug_client_info(
8828 self,
8829 ) -> Option<(NodeSetDebugClientInfoRequest, BufferCollectionTokenControlHandle)> {
8830 if let BufferCollectionTokenRequest::SetDebugClientInfo { payload, control_handle } = self {
8831 Some((payload, control_handle))
8832 } else {
8833 None
8834 }
8835 }
8836
8837 #[allow(irrefutable_let_patterns)]
8838 pub fn into_set_debug_timeout_log_deadline(
8839 self,
8840 ) -> Option<(NodeSetDebugTimeoutLogDeadlineRequest, BufferCollectionTokenControlHandle)> {
8841 if let BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {
8842 payload,
8843 control_handle,
8844 } = self
8845 {
8846 Some((payload, control_handle))
8847 } else {
8848 None
8849 }
8850 }
8851
8852 #[allow(irrefutable_let_patterns)]
8853 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenControlHandle)> {
8854 if let BufferCollectionTokenRequest::SetVerboseLogging { control_handle } = self {
8855 Some((control_handle))
8856 } else {
8857 None
8858 }
8859 }
8860
8861 #[allow(irrefutable_let_patterns)]
8862 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGetNodeRefResponder)> {
8863 if let BufferCollectionTokenRequest::GetNodeRef { responder } = self {
8864 Some((responder))
8865 } else {
8866 None
8867 }
8868 }
8869
8870 #[allow(irrefutable_let_patterns)]
8871 pub fn into_is_alternate_for(
8872 self,
8873 ) -> Option<(NodeIsAlternateForRequest, BufferCollectionTokenIsAlternateForResponder)> {
8874 if let BufferCollectionTokenRequest::IsAlternateFor { payload, responder } = self {
8875 Some((payload, responder))
8876 } else {
8877 None
8878 }
8879 }
8880
8881 #[allow(irrefutable_let_patterns)]
8882 pub fn into_get_buffer_collection_id(
8883 self,
8884 ) -> Option<(BufferCollectionTokenGetBufferCollectionIdResponder)> {
8885 if let BufferCollectionTokenRequest::GetBufferCollectionId { responder } = self {
8886 Some((responder))
8887 } else {
8888 None
8889 }
8890 }
8891
8892 #[allow(irrefutable_let_patterns)]
8893 pub fn into_set_weak(self) -> Option<(BufferCollectionTokenControlHandle)> {
8894 if let BufferCollectionTokenRequest::SetWeak { control_handle } = self {
8895 Some((control_handle))
8896 } else {
8897 None
8898 }
8899 }
8900
8901 #[allow(irrefutable_let_patterns)]
8902 pub fn into_set_weak_ok(
8903 self,
8904 ) -> Option<(NodeSetWeakOkRequest, BufferCollectionTokenControlHandle)> {
8905 if let BufferCollectionTokenRequest::SetWeakOk { payload, control_handle } = self {
8906 Some((payload, control_handle))
8907 } else {
8908 None
8909 }
8910 }
8911
8912 #[allow(irrefutable_let_patterns)]
8913 pub fn into_attach_node_tracking(
8914 self,
8915 ) -> Option<(NodeAttachNodeTrackingRequest, BufferCollectionTokenControlHandle)> {
8916 if let BufferCollectionTokenRequest::AttachNodeTracking { payload, control_handle } = self {
8917 Some((payload, control_handle))
8918 } else {
8919 None
8920 }
8921 }
8922
8923 #[allow(irrefutable_let_patterns)]
8924 pub fn into_duplicate_sync(
8925 self,
8926 ) -> Option<(
8927 BufferCollectionTokenDuplicateSyncRequest,
8928 BufferCollectionTokenDuplicateSyncResponder,
8929 )> {
8930 if let BufferCollectionTokenRequest::DuplicateSync { payload, responder } = self {
8931 Some((payload, responder))
8932 } else {
8933 None
8934 }
8935 }
8936
8937 #[allow(irrefutable_let_patterns)]
8938 pub fn into_duplicate(
8939 self,
8940 ) -> Option<(BufferCollectionTokenDuplicateRequest, BufferCollectionTokenControlHandle)> {
8941 if let BufferCollectionTokenRequest::Duplicate { payload, control_handle } = self {
8942 Some((payload, control_handle))
8943 } else {
8944 None
8945 }
8946 }
8947
8948 #[allow(irrefutable_let_patterns)]
8949 pub fn into_set_dispensable(self) -> Option<(BufferCollectionTokenControlHandle)> {
8950 if let BufferCollectionTokenRequest::SetDispensable { control_handle } = self {
8951 Some((control_handle))
8952 } else {
8953 None
8954 }
8955 }
8956
8957 #[allow(irrefutable_let_patterns)]
8958 pub fn into_create_buffer_collection_token_group(
8959 self,
8960 ) -> Option<(
8961 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
8962 BufferCollectionTokenControlHandle,
8963 )> {
8964 if let BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {
8965 payload,
8966 control_handle,
8967 } = self
8968 {
8969 Some((payload, control_handle))
8970 } else {
8971 None
8972 }
8973 }
8974
8975 /// Name of the method defined in FIDL
8976 pub fn method_name(&self) -> &'static str {
8977 match *self {
8978 BufferCollectionTokenRequest::Sync { .. } => "sync",
8979 BufferCollectionTokenRequest::Release { .. } => "release",
8980 BufferCollectionTokenRequest::SetName { .. } => "set_name",
8981 BufferCollectionTokenRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
8982 BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline { .. } => {
8983 "set_debug_timeout_log_deadline"
8984 }
8985 BufferCollectionTokenRequest::SetVerboseLogging { .. } => "set_verbose_logging",
8986 BufferCollectionTokenRequest::GetNodeRef { .. } => "get_node_ref",
8987 BufferCollectionTokenRequest::IsAlternateFor { .. } => "is_alternate_for",
8988 BufferCollectionTokenRequest::GetBufferCollectionId { .. } => {
8989 "get_buffer_collection_id"
8990 }
8991 BufferCollectionTokenRequest::SetWeak { .. } => "set_weak",
8992 BufferCollectionTokenRequest::SetWeakOk { .. } => "set_weak_ok",
8993 BufferCollectionTokenRequest::AttachNodeTracking { .. } => "attach_node_tracking",
8994 BufferCollectionTokenRequest::DuplicateSync { .. } => "duplicate_sync",
8995 BufferCollectionTokenRequest::Duplicate { .. } => "duplicate",
8996 BufferCollectionTokenRequest::SetDispensable { .. } => "set_dispensable",
8997 BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup { .. } => {
8998 "create_buffer_collection_token_group"
8999 }
9000 BufferCollectionTokenRequest::_UnknownMethod {
9001 method_type: fidl::MethodType::OneWay,
9002 ..
9003 } => "unknown one-way method",
9004 BufferCollectionTokenRequest::_UnknownMethod {
9005 method_type: fidl::MethodType::TwoWay,
9006 ..
9007 } => "unknown two-way method",
9008 }
9009 }
9010}
9011
9012#[derive(Debug, Clone)]
9013pub struct BufferCollectionTokenControlHandle {
9014 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9015}
9016
9017impl fidl::endpoints::ControlHandle for BufferCollectionTokenControlHandle {
9018 fn shutdown(&self) {
9019 self.inner.shutdown()
9020 }
9021
9022 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
9023 self.inner.shutdown_with_epitaph(status)
9024 }
9025
9026 fn is_closed(&self) -> bool {
9027 self.inner.channel().is_closed()
9028 }
9029 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
9030 self.inner.channel().on_closed()
9031 }
9032
9033 #[cfg(target_os = "fuchsia")]
9034 fn signal_peer(
9035 &self,
9036 clear_mask: zx::Signals,
9037 set_mask: zx::Signals,
9038 ) -> Result<(), zx_status::Status> {
9039 use fidl::Peered;
9040 self.inner.channel().signal_peer(clear_mask, set_mask)
9041 }
9042}
9043
9044impl BufferCollectionTokenControlHandle {}
9045
9046#[must_use = "FIDL methods require a response to be sent"]
9047#[derive(Debug)]
9048pub struct BufferCollectionTokenSyncResponder {
9049 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
9050 tx_id: u32,
9051}
9052
9053/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
9054/// if the responder is dropped without sending a response, so that the client
9055/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9056impl std::ops::Drop for BufferCollectionTokenSyncResponder {
9057 fn drop(&mut self) {
9058 self.control_handle.shutdown();
9059 // Safety: drops once, never accessed again
9060 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9061 }
9062}
9063
9064impl fidl::endpoints::Responder for BufferCollectionTokenSyncResponder {
9065 type ControlHandle = BufferCollectionTokenControlHandle;
9066
9067 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
9068 &self.control_handle
9069 }
9070
9071 fn drop_without_shutdown(mut self) {
9072 // Safety: drops once, never accessed again due to mem::forget
9073 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9074 // Prevent Drop from running (which would shut down the channel)
9075 std::mem::forget(self);
9076 }
9077}
9078
9079impl BufferCollectionTokenSyncResponder {
9080 /// Sends a response to the FIDL transaction.
9081 ///
9082 /// Sets the channel to shutdown if an error occurs.
9083 pub fn send(self) -> Result<(), fidl::Error> {
9084 let _result = self.send_raw();
9085 if _result.is_err() {
9086 self.control_handle.shutdown();
9087 }
9088 self.drop_without_shutdown();
9089 _result
9090 }
9091
9092 /// Similar to "send" but does not shutdown the channel if an error occurs.
9093 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
9094 let _result = self.send_raw();
9095 self.drop_without_shutdown();
9096 _result
9097 }
9098
9099 fn send_raw(&self) -> Result<(), fidl::Error> {
9100 self.control_handle.inner.send::<fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>>(
9101 fidl::encoding::Flexible::new(()),
9102 self.tx_id,
9103 0x11ac2555cf575b54,
9104 fidl::encoding::DynamicFlags::FLEXIBLE,
9105 )
9106 }
9107}
9108
9109#[must_use = "FIDL methods require a response to be sent"]
9110#[derive(Debug)]
9111pub struct BufferCollectionTokenGetNodeRefResponder {
9112 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
9113 tx_id: u32,
9114}
9115
9116/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
9117/// if the responder is dropped without sending a response, so that the client
9118/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9119impl std::ops::Drop for BufferCollectionTokenGetNodeRefResponder {
9120 fn drop(&mut self) {
9121 self.control_handle.shutdown();
9122 // Safety: drops once, never accessed again
9123 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9124 }
9125}
9126
9127impl fidl::endpoints::Responder for BufferCollectionTokenGetNodeRefResponder {
9128 type ControlHandle = BufferCollectionTokenControlHandle;
9129
9130 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
9131 &self.control_handle
9132 }
9133
9134 fn drop_without_shutdown(mut self) {
9135 // Safety: drops once, never accessed again due to mem::forget
9136 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9137 // Prevent Drop from running (which would shut down the channel)
9138 std::mem::forget(self);
9139 }
9140}
9141
9142impl BufferCollectionTokenGetNodeRefResponder {
9143 /// Sends a response to the FIDL transaction.
9144 ///
9145 /// Sets the channel to shutdown if an error occurs.
9146 pub fn send(self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
9147 let _result = self.send_raw(payload);
9148 if _result.is_err() {
9149 self.control_handle.shutdown();
9150 }
9151 self.drop_without_shutdown();
9152 _result
9153 }
9154
9155 /// Similar to "send" but does not shutdown the channel if an error occurs.
9156 pub fn send_no_shutdown_on_err(
9157 self,
9158 mut payload: NodeGetNodeRefResponse,
9159 ) -> Result<(), fidl::Error> {
9160 let _result = self.send_raw(payload);
9161 self.drop_without_shutdown();
9162 _result
9163 }
9164
9165 fn send_raw(&self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
9166 self.control_handle.inner.send::<fidl::encoding::FlexibleType<NodeGetNodeRefResponse>>(
9167 fidl::encoding::Flexible::new(&mut payload),
9168 self.tx_id,
9169 0x5b3d0e51614df053,
9170 fidl::encoding::DynamicFlags::FLEXIBLE,
9171 )
9172 }
9173}
9174
9175#[must_use = "FIDL methods require a response to be sent"]
9176#[derive(Debug)]
9177pub struct BufferCollectionTokenIsAlternateForResponder {
9178 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
9179 tx_id: u32,
9180}
9181
9182/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
9183/// if the responder is dropped without sending a response, so that the client
9184/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9185impl std::ops::Drop for BufferCollectionTokenIsAlternateForResponder {
9186 fn drop(&mut self) {
9187 self.control_handle.shutdown();
9188 // Safety: drops once, never accessed again
9189 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9190 }
9191}
9192
9193impl fidl::endpoints::Responder for BufferCollectionTokenIsAlternateForResponder {
9194 type ControlHandle = BufferCollectionTokenControlHandle;
9195
9196 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
9197 &self.control_handle
9198 }
9199
9200 fn drop_without_shutdown(mut self) {
9201 // Safety: drops once, never accessed again due to mem::forget
9202 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9203 // Prevent Drop from running (which would shut down the channel)
9204 std::mem::forget(self);
9205 }
9206}
9207
9208impl BufferCollectionTokenIsAlternateForResponder {
9209 /// Sends a response to the FIDL transaction.
9210 ///
9211 /// Sets the channel to shutdown if an error occurs.
9212 pub fn send(
9213 self,
9214 mut result: Result<&NodeIsAlternateForResponse, Error>,
9215 ) -> Result<(), fidl::Error> {
9216 let _result = self.send_raw(result);
9217 if _result.is_err() {
9218 self.control_handle.shutdown();
9219 }
9220 self.drop_without_shutdown();
9221 _result
9222 }
9223
9224 /// Similar to "send" but does not shutdown the channel if an error occurs.
9225 pub fn send_no_shutdown_on_err(
9226 self,
9227 mut result: Result<&NodeIsAlternateForResponse, Error>,
9228 ) -> Result<(), fidl::Error> {
9229 let _result = self.send_raw(result);
9230 self.drop_without_shutdown();
9231 _result
9232 }
9233
9234 fn send_raw(
9235 &self,
9236 mut result: Result<&NodeIsAlternateForResponse, Error>,
9237 ) -> Result<(), fidl::Error> {
9238 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
9239 NodeIsAlternateForResponse,
9240 Error,
9241 >>(
9242 fidl::encoding::FlexibleResult::new(result),
9243 self.tx_id,
9244 0x3a58e00157e0825,
9245 fidl::encoding::DynamicFlags::FLEXIBLE,
9246 )
9247 }
9248}
9249
9250#[must_use = "FIDL methods require a response to be sent"]
9251#[derive(Debug)]
9252pub struct BufferCollectionTokenGetBufferCollectionIdResponder {
9253 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
9254 tx_id: u32,
9255}
9256
9257/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
9258/// if the responder is dropped without sending a response, so that the client
9259/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9260impl std::ops::Drop for BufferCollectionTokenGetBufferCollectionIdResponder {
9261 fn drop(&mut self) {
9262 self.control_handle.shutdown();
9263 // Safety: drops once, never accessed again
9264 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9265 }
9266}
9267
9268impl fidl::endpoints::Responder for BufferCollectionTokenGetBufferCollectionIdResponder {
9269 type ControlHandle = BufferCollectionTokenControlHandle;
9270
9271 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
9272 &self.control_handle
9273 }
9274
9275 fn drop_without_shutdown(mut self) {
9276 // Safety: drops once, never accessed again due to mem::forget
9277 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9278 // Prevent Drop from running (which would shut down the channel)
9279 std::mem::forget(self);
9280 }
9281}
9282
9283impl BufferCollectionTokenGetBufferCollectionIdResponder {
9284 /// Sends a response to the FIDL transaction.
9285 ///
9286 /// Sets the channel to shutdown if an error occurs.
9287 pub fn send(self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
9288 let _result = self.send_raw(payload);
9289 if _result.is_err() {
9290 self.control_handle.shutdown();
9291 }
9292 self.drop_without_shutdown();
9293 _result
9294 }
9295
9296 /// Similar to "send" but does not shutdown the channel if an error occurs.
9297 pub fn send_no_shutdown_on_err(
9298 self,
9299 mut payload: &NodeGetBufferCollectionIdResponse,
9300 ) -> Result<(), fidl::Error> {
9301 let _result = self.send_raw(payload);
9302 self.drop_without_shutdown();
9303 _result
9304 }
9305
9306 fn send_raw(&self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
9307 self.control_handle
9308 .inner
9309 .send::<fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>>(
9310 fidl::encoding::Flexible::new(payload),
9311 self.tx_id,
9312 0x77d19a494b78ba8c,
9313 fidl::encoding::DynamicFlags::FLEXIBLE,
9314 )
9315 }
9316}
9317
9318#[must_use = "FIDL methods require a response to be sent"]
9319#[derive(Debug)]
9320pub struct BufferCollectionTokenDuplicateSyncResponder {
9321 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
9322 tx_id: u32,
9323}
9324
9325/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
9326/// if the responder is dropped without sending a response, so that the client
9327/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9328impl std::ops::Drop for BufferCollectionTokenDuplicateSyncResponder {
9329 fn drop(&mut self) {
9330 self.control_handle.shutdown();
9331 // Safety: drops once, never accessed again
9332 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9333 }
9334}
9335
9336impl fidl::endpoints::Responder for BufferCollectionTokenDuplicateSyncResponder {
9337 type ControlHandle = BufferCollectionTokenControlHandle;
9338
9339 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
9340 &self.control_handle
9341 }
9342
9343 fn drop_without_shutdown(mut self) {
9344 // Safety: drops once, never accessed again due to mem::forget
9345 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9346 // Prevent Drop from running (which would shut down the channel)
9347 std::mem::forget(self);
9348 }
9349}
9350
9351impl BufferCollectionTokenDuplicateSyncResponder {
9352 /// Sends a response to the FIDL transaction.
9353 ///
9354 /// Sets the channel to shutdown if an error occurs.
9355 pub fn send(
9356 self,
9357 mut payload: BufferCollectionTokenDuplicateSyncResponse,
9358 ) -> Result<(), fidl::Error> {
9359 let _result = self.send_raw(payload);
9360 if _result.is_err() {
9361 self.control_handle.shutdown();
9362 }
9363 self.drop_without_shutdown();
9364 _result
9365 }
9366
9367 /// Similar to "send" but does not shutdown the channel if an error occurs.
9368 pub fn send_no_shutdown_on_err(
9369 self,
9370 mut payload: BufferCollectionTokenDuplicateSyncResponse,
9371 ) -> Result<(), fidl::Error> {
9372 let _result = self.send_raw(payload);
9373 self.drop_without_shutdown();
9374 _result
9375 }
9376
9377 fn send_raw(
9378 &self,
9379 mut payload: BufferCollectionTokenDuplicateSyncResponse,
9380 ) -> Result<(), fidl::Error> {
9381 self.control_handle.inner.send::<fidl::encoding::FlexibleType<
9382 BufferCollectionTokenDuplicateSyncResponse,
9383 >>(
9384 fidl::encoding::Flexible::new(&mut payload),
9385 self.tx_id,
9386 0x1c1af9919d1ca45c,
9387 fidl::encoding::DynamicFlags::FLEXIBLE,
9388 )
9389 }
9390}
9391
9392#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
9393pub struct BufferCollectionTokenGroupMarker;
9394
9395impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenGroupMarker {
9396 type Proxy = BufferCollectionTokenGroupProxy;
9397 type RequestStream = BufferCollectionTokenGroupRequestStream;
9398 #[cfg(target_os = "fuchsia")]
9399 type SynchronousProxy = BufferCollectionTokenGroupSynchronousProxy;
9400
9401 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionTokenGroup";
9402}
9403
9404pub trait BufferCollectionTokenGroupProxyInterface: Send + Sync {
9405 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
9406 fn r#sync(&self) -> Self::SyncResponseFut;
9407 fn r#release(&self) -> Result<(), fidl::Error>;
9408 fn r#set_name(&self, payload: &NodeSetNameRequest) -> Result<(), fidl::Error>;
9409 fn r#set_debug_client_info(
9410 &self,
9411 payload: &NodeSetDebugClientInfoRequest,
9412 ) -> Result<(), fidl::Error>;
9413 fn r#set_debug_timeout_log_deadline(
9414 &self,
9415 payload: &NodeSetDebugTimeoutLogDeadlineRequest,
9416 ) -> Result<(), fidl::Error>;
9417 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
9418 type GetNodeRefResponseFut: std::future::Future<Output = Result<NodeGetNodeRefResponse, fidl::Error>>
9419 + Send;
9420 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
9421 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
9422 + Send;
9423 fn r#is_alternate_for(
9424 &self,
9425 payload: NodeIsAlternateForRequest,
9426 ) -> Self::IsAlternateForResponseFut;
9427 type GetBufferCollectionIdResponseFut: std::future::Future<Output = Result<NodeGetBufferCollectionIdResponse, fidl::Error>>
9428 + Send;
9429 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut;
9430 fn r#set_weak(&self) -> Result<(), fidl::Error>;
9431 fn r#set_weak_ok(&self, payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error>;
9432 fn r#attach_node_tracking(
9433 &self,
9434 payload: NodeAttachNodeTrackingRequest,
9435 ) -> Result<(), fidl::Error>;
9436 fn r#create_child(
9437 &self,
9438 payload: BufferCollectionTokenGroupCreateChildRequest,
9439 ) -> Result<(), fidl::Error>;
9440 type CreateChildrenSyncResponseFut: std::future::Future<
9441 Output = Result<BufferCollectionTokenGroupCreateChildrenSyncResponse, fidl::Error>,
9442 > + Send;
9443 fn r#create_children_sync(
9444 &self,
9445 payload: &BufferCollectionTokenGroupCreateChildrenSyncRequest,
9446 ) -> Self::CreateChildrenSyncResponseFut;
9447 fn r#all_children_present(&self) -> Result<(), fidl::Error>;
9448}
9449#[derive(Debug)]
9450#[cfg(target_os = "fuchsia")]
9451pub struct BufferCollectionTokenGroupSynchronousProxy {
9452 client: fidl::client::sync::Client,
9453}
9454
9455#[cfg(target_os = "fuchsia")]
9456impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenGroupSynchronousProxy {
9457 type Proxy = BufferCollectionTokenGroupProxy;
9458 type Protocol = BufferCollectionTokenGroupMarker;
9459
9460 fn from_channel(inner: fidl::Channel) -> Self {
9461 Self::new(inner)
9462 }
9463
9464 fn into_channel(self) -> fidl::Channel {
9465 self.client.into_channel()
9466 }
9467
9468 fn as_channel(&self) -> &fidl::Channel {
9469 self.client.as_channel()
9470 }
9471}
9472
9473#[cfg(target_os = "fuchsia")]
9474impl BufferCollectionTokenGroupSynchronousProxy {
9475 pub fn new(channel: fidl::Channel) -> Self {
9476 Self { client: fidl::client::sync::Client::new(channel) }
9477 }
9478
9479 pub fn into_channel(self) -> fidl::Channel {
9480 self.client.into_channel()
9481 }
9482
9483 /// Waits until an event arrives and returns it. It is safe for other
9484 /// threads to make concurrent requests while waiting for an event.
9485 pub fn wait_for_event(
9486 &self,
9487 deadline: zx::MonotonicInstant,
9488 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
9489 BufferCollectionTokenGroupEvent::decode(
9490 self.client.wait_for_event::<BufferCollectionTokenGroupMarker>(deadline)?,
9491 )
9492 }
9493
9494 /// Ensure that previous messages have been received server side. This is
9495 /// particularly useful after previous messages that created new tokens,
9496 /// because a token must be known to the sysmem server before sending the
9497 /// token to another participant.
9498 ///
9499 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
9500 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
9501 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
9502 /// to mitigate the possibility of a hostile/fake
9503 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
9504 /// Another way is to pass the token to
9505 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
9506 /// the token as part of exchanging it for a
9507 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
9508 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
9509 /// of stalling.
9510 ///
9511 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
9512 /// and then starting and completing a `Sync`, it's then safe to send the
9513 /// `BufferCollectionToken` client ends to other participants knowing the
9514 /// server will recognize the tokens when they're sent by the other
9515 /// participants to sysmem in a
9516 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
9517 /// efficient way to create tokens while avoiding unnecessary round trips.
9518 ///
9519 /// Other options include waiting for each
9520 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
9521 /// individually (using separate call to `Sync` after each), or calling
9522 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
9523 /// converted to a `BufferCollection` via
9524 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
9525 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
9526 /// the sync step and can create multiple tokens at once.
9527 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
9528 let _response = self.client.send_query::<
9529 fidl::encoding::EmptyPayload,
9530 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
9531 BufferCollectionTokenGroupMarker,
9532 >(
9533 (),
9534 0x11ac2555cf575b54,
9535 fidl::encoding::DynamicFlags::FLEXIBLE,
9536 ___deadline,
9537 )?
9538 .into_result::<BufferCollectionTokenGroupMarker>("sync")?;
9539 Ok(_response)
9540 }
9541
9542 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
9543 ///
9544 /// Normally a participant will convert a `BufferCollectionToken` into a
9545 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
9546 /// `Release` via the token (and then close the channel immediately or
9547 /// shortly later in response to server closing the server end), which
9548 /// avoids causing buffer collection failure. Without a prior `Release`,
9549 /// closing the `BufferCollectionToken` client end will cause buffer
9550 /// collection failure.
9551 ///
9552 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
9553 ///
9554 /// By default the server handles unexpected closure of a
9555 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
9556 /// first) by failing the buffer collection. Partly this is to expedite
9557 /// closing VMO handles to reclaim memory when any participant fails. If a
9558 /// participant would like to cleanly close a `BufferCollection` without
9559 /// causing buffer collection failure, the participant can send `Release`
9560 /// before closing the `BufferCollection` client end. The `Release` can
9561 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
9562 /// buffer collection won't require constraints from this node in order to
9563 /// allocate. If after `SetConstraints`, the constraints are retained and
9564 /// aggregated, despite the lack of `BufferCollection` connection at the
9565 /// time of constraints aggregation.
9566 ///
9567 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
9568 ///
9569 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
9570 /// end (without `Release` first) will trigger failure of the buffer
9571 /// collection. To close a `BufferCollectionTokenGroup` channel without
9572 /// failing the buffer collection, ensure that AllChildrenPresent() has been
9573 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
9574 /// client end.
9575 ///
9576 /// If `Release` occurs before
9577 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
9578 /// buffer collection will fail (triggered by reception of `Release` without
9579 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
9580 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
9581 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
9582 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
9583 /// close requires `AllChildrenPresent` (if not already sent), then
9584 /// `Release`, then close client end.
9585 ///
9586 /// If `Release` occurs after `AllChildrenPresent`, the children and all
9587 /// their constraints remain intact (just as they would if the
9588 /// `BufferCollectionTokenGroup` channel had remained open), and the client
9589 /// end close doesn't trigger buffer collection failure.
9590 ///
9591 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
9592 ///
9593 /// For brevity, the per-channel-protocol paragraphs above ignore the
9594 /// separate failure domain created by
9595 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
9596 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
9597 /// unexpectedly closes (without `Release` first) and that client end is
9598 /// under a failure domain, instead of failing the whole buffer collection,
9599 /// the failure domain is failed, but the buffer collection itself is
9600 /// isolated from failure of the failure domain. Such failure domains can be
9601 /// nested, in which case only the inner-most failure domain in which the
9602 /// `Node` resides fails.
9603 pub fn r#release(&self) -> Result<(), fidl::Error> {
9604 self.client.send::<fidl::encoding::EmptyPayload>(
9605 (),
9606 0x6a5cae7d6d6e04c6,
9607 fidl::encoding::DynamicFlags::FLEXIBLE,
9608 )
9609 }
9610
9611 /// Set a name for VMOs in this buffer collection.
9612 ///
9613 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
9614 /// will be truncated to fit. The name of the vmo will be suffixed with the
9615 /// buffer index within the collection (if the suffix fits within
9616 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
9617 /// listed in the inspect data.
9618 ///
9619 /// The name only affects VMOs allocated after the name is set; this call
9620 /// does not rename existing VMOs. If multiple clients set different names
9621 /// then the larger priority value will win. Setting a new name with the
9622 /// same priority as a prior name doesn't change the name.
9623 ///
9624 /// All table fields are currently required.
9625 ///
9626 /// + request `priority` The name is only set if this is the first `SetName`
9627 /// or if `priority` is greater than any previous `priority` value in
9628 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
9629 /// + request `name` The name for VMOs created under this buffer collection.
9630 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
9631 self.client.send::<NodeSetNameRequest>(
9632 payload,
9633 0xb41f1624f48c1e9,
9634 fidl::encoding::DynamicFlags::FLEXIBLE,
9635 )
9636 }
9637
9638 /// Set information about the current client that can be used by sysmem to
9639 /// help diagnose leaking memory and allocation stalls waiting for a
9640 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
9641 ///
9642 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
9643 /// `Node`(s) derived from this `Node`, unless overriden by
9644 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
9645 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
9646 ///
9647 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
9648 /// `Allocator` is the most efficient way to ensure that all
9649 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
9650 /// set, and is also more efficient than separately sending the same debug
9651 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
9652 /// created [`fuchsia.sysmem2/Node`].
9653 ///
9654 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
9655 /// indicate which client is closing their channel first, leading to subtree
9656 /// failure (which can be normal if the purpose of the subtree is over, but
9657 /// if happening earlier than expected, the client-channel-specific name can
9658 /// help diagnose where the failure is first coming from, from sysmem's
9659 /// point of view).
9660 ///
9661 /// All table fields are currently required.
9662 ///
9663 /// + request `name` This can be an arbitrary string, but the current
9664 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
9665 /// + request `id` This can be an arbitrary id, but the current process ID
9666 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
9667 pub fn r#set_debug_client_info(
9668 &self,
9669 mut payload: &NodeSetDebugClientInfoRequest,
9670 ) -> Result<(), fidl::Error> {
9671 self.client.send::<NodeSetDebugClientInfoRequest>(
9672 payload,
9673 0x5cde8914608d99b1,
9674 fidl::encoding::DynamicFlags::FLEXIBLE,
9675 )
9676 }
9677
9678 /// Sysmem logs a warning if sysmem hasn't seen
9679 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
9680 /// within 5 seconds after creation of a new collection.
9681 ///
9682 /// Clients can call this method to change when the log is printed. If
9683 /// multiple client set the deadline, it's unspecified which deadline will
9684 /// take effect.
9685 ///
9686 /// In most cases the default works well.
9687 ///
9688 /// All table fields are currently required.
9689 ///
9690 /// + request `deadline` The time at which sysmem will start trying to log
9691 /// the warning, unless all constraints are with sysmem by then.
9692 pub fn r#set_debug_timeout_log_deadline(
9693 &self,
9694 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
9695 ) -> Result<(), fidl::Error> {
9696 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
9697 payload,
9698 0x716b0af13d5c0806,
9699 fidl::encoding::DynamicFlags::FLEXIBLE,
9700 )
9701 }
9702
9703 /// This enables verbose logging for the buffer collection.
9704 ///
9705 /// Verbose logging includes constraints set via
9706 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
9707 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
9708 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
9709 /// the tree of `Node`(s).
9710 ///
9711 /// Normally sysmem prints only a single line complaint when aggregation
9712 /// fails, with just the specific detailed reason that aggregation failed,
9713 /// with little surrounding context. While this is often enough to diagnose
9714 /// a problem if only a small change was made and everything was working
9715 /// before the small change, it's often not particularly helpful for getting
9716 /// a new buffer collection to work for the first time. Especially with
9717 /// more complex trees of nodes, involving things like
9718 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
9719 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
9720 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
9721 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
9722 /// looks like and why it's failing a logical allocation, or why a tree or
9723 /// subtree is failing sooner than expected.
9724 ///
9725 /// The intent of the extra logging is to be acceptable from a performance
9726 /// point of view, under the assumption that verbose logging is only enabled
9727 /// on a low number of buffer collections. If we're not tracking down a bug,
9728 /// we shouldn't send this message.
9729 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
9730 self.client.send::<fidl::encoding::EmptyPayload>(
9731 (),
9732 0x5209c77415b4dfad,
9733 fidl::encoding::DynamicFlags::FLEXIBLE,
9734 )
9735 }
9736
9737 /// This gets a handle that can be used as a parameter to
9738 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
9739 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
9740 /// client obtained this handle from this `Node`.
9741 ///
9742 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
9743 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
9744 /// despite the two calls typically being on different channels.
9745 ///
9746 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
9747 ///
9748 /// All table fields are currently required.
9749 ///
9750 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
9751 /// different `Node` channel, to prove that the client obtained the handle
9752 /// from this `Node`.
9753 pub fn r#get_node_ref(
9754 &self,
9755 ___deadline: zx::MonotonicInstant,
9756 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
9757 let _response = self.client.send_query::<
9758 fidl::encoding::EmptyPayload,
9759 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
9760 BufferCollectionTokenGroupMarker,
9761 >(
9762 (),
9763 0x5b3d0e51614df053,
9764 fidl::encoding::DynamicFlags::FLEXIBLE,
9765 ___deadline,
9766 )?
9767 .into_result::<BufferCollectionTokenGroupMarker>("get_node_ref")?;
9768 Ok(_response)
9769 }
9770
9771 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
9772 /// rooted at a different child token of a common parent
9773 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
9774 /// passed-in `node_ref`.
9775 ///
9776 /// This call is for assisting with admission control de-duplication, and
9777 /// with debugging.
9778 ///
9779 /// The `node_ref` must be obtained using
9780 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
9781 ///
9782 /// The `node_ref` can be a duplicated handle; it's not necessary to call
9783 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
9784 ///
9785 /// If a calling token may not actually be a valid token at all due to a
9786 /// potentially hostile/untrusted provider of the token, call
9787 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
9788 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
9789 /// never responds due to a calling token not being a real token (not really
9790 /// talking to sysmem). Another option is to call
9791 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
9792 /// which also validates the token along with converting it to a
9793 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
9794 ///
9795 /// All table fields are currently required.
9796 ///
9797 /// - response `is_alternate`
9798 /// - true: The first parent node in common between the calling node and
9799 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
9800 /// that the calling `Node` and the `node_ref` `Node` will not have both
9801 /// their constraints apply - rather sysmem will choose one or the other
9802 /// of the constraints - never both. This is because only one child of
9803 /// a `BufferCollectionTokenGroup` is selected during logical
9804 /// allocation, with only that one child's subtree contributing to
9805 /// constraints aggregation.
9806 /// - false: The first parent node in common between the calling `Node`
9807 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
9808 /// Currently, this means the first parent node in common is a
9809 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
9810 /// `Release`ed). This means that the calling `Node` and the `node_ref`
9811 /// `Node` may have both their constraints apply during constraints
9812 /// aggregation of the logical allocation, if both `Node`(s) are
9813 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
9814 /// this case, there is no `BufferCollectionTokenGroup` that will
9815 /// directly prevent the two `Node`(s) from both being selected and
9816 /// their constraints both aggregated, but even when false, one or both
9817 /// `Node`(s) may still be eliminated from consideration if one or both
9818 /// `Node`(s) has a direct or indirect parent
9819 /// `BufferCollectionTokenGroup` which selects a child subtree other
9820 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
9821 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
9822 /// associated with the same buffer collection as the calling `Node`.
9823 /// Another reason for this error is if the `node_ref` is an
9824 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
9825 /// a real `node_ref` obtained from `GetNodeRef`.
9826 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
9827 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
9828 /// the needed rights expected on a real `node_ref`.
9829 /// * No other failing status codes are returned by this call. However,
9830 /// sysmem may add additional codes in future, so the client should have
9831 /// sensible default handling for any failing status code.
9832 pub fn r#is_alternate_for(
9833 &self,
9834 mut payload: NodeIsAlternateForRequest,
9835 ___deadline: zx::MonotonicInstant,
9836 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
9837 let _response = self.client.send_query::<
9838 NodeIsAlternateForRequest,
9839 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
9840 BufferCollectionTokenGroupMarker,
9841 >(
9842 &mut payload,
9843 0x3a58e00157e0825,
9844 fidl::encoding::DynamicFlags::FLEXIBLE,
9845 ___deadline,
9846 )?
9847 .into_result::<BufferCollectionTokenGroupMarker>("is_alternate_for")?;
9848 Ok(_response.map(|x| x))
9849 }
9850
9851 /// Get the buffer collection ID. This ID is also available from
9852 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
9853 /// within the collection).
9854 ///
9855 /// This call is mainly useful in situations where we can't convey a
9856 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
9857 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
9858 /// handle, which can be joined back up with a `BufferCollection` client end
9859 /// that was created via a different path. Prefer to convey a
9860 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
9861 ///
9862 /// Trusting a `buffer_collection_id` value from a source other than sysmem
9863 /// is analogous to trusting a koid value from a source other than zircon.
9864 /// Both should be avoided unless really necessary, and both require
9865 /// caution. In some situations it may be reasonable to refer to a
9866 /// pre-established `BufferCollection` by `buffer_collection_id` via a
9867 /// protocol for efficiency reasons, but an incoming value purporting to be
9868 /// a `buffer_collection_id` is not sufficient alone to justify granting the
9869 /// sender of the `buffer_collection_id` any capability. The sender must
9870 /// first prove to a receiver that the sender has/had a VMO or has/had a
9871 /// `BufferCollectionToken` to the same collection by sending a handle that
9872 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
9873 /// `buffer_collection_id` value. The receiver should take care to avoid
9874 /// assuming that a sender had a `BufferCollectionToken` in cases where the
9875 /// sender has only proven that the sender had a VMO.
9876 ///
9877 /// - response `buffer_collection_id` This ID is unique per buffer
9878 /// collection per boot. Each buffer is uniquely identified by the
9879 /// `buffer_collection_id` and `buffer_index` together.
9880 pub fn r#get_buffer_collection_id(
9881 &self,
9882 ___deadline: zx::MonotonicInstant,
9883 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
9884 let _response = self.client.send_query::<
9885 fidl::encoding::EmptyPayload,
9886 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
9887 BufferCollectionTokenGroupMarker,
9888 >(
9889 (),
9890 0x77d19a494b78ba8c,
9891 fidl::encoding::DynamicFlags::FLEXIBLE,
9892 ___deadline,
9893 )?
9894 .into_result::<BufferCollectionTokenGroupMarker>("get_buffer_collection_id")?;
9895 Ok(_response)
9896 }
9897
9898 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
9899 /// created after this message to weak, which means that a client's `Node`
9900 /// client end (or a child created after this message) is not alone
9901 /// sufficient to keep allocated VMOs alive.
9902 ///
9903 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
9904 /// `close_weak_asap`.
9905 ///
9906 /// This message is only permitted before the `Node` becomes ready for
9907 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
9908 /// * `BufferCollectionToken`: any time
9909 /// * `BufferCollection`: before `SetConstraints`
9910 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
9911 ///
9912 /// Currently, no conversion from strong `Node` to weak `Node` after ready
9913 /// for allocation is provided, but a client can simulate that by creating
9914 /// an additional `Node` before allocation and setting that additional
9915 /// `Node` to weak, and then potentially at some point later sending
9916 /// `Release` and closing the client end of the client's strong `Node`, but
9917 /// keeping the client's weak `Node`.
9918 ///
9919 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
9920 /// collection failure (all `Node` client end(s) will see
9921 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
9922 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
9923 /// this situation until all `Node`(s) are ready for allocation. For initial
9924 /// allocation to succeed, at least one strong `Node` is required to exist
9925 /// at allocation time, but after that client receives VMO handles, that
9926 /// client can `BufferCollection.Release` and close the client end without
9927 /// causing this type of failure.
9928 ///
9929 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
9930 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
9931 /// separately as appropriate.
9932 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
9933 self.client.send::<fidl::encoding::EmptyPayload>(
9934 (),
9935 0x22dd3ea514eeffe1,
9936 fidl::encoding::DynamicFlags::FLEXIBLE,
9937 )
9938 }
9939
9940 /// This indicates to sysmem that the client is prepared to pay attention to
9941 /// `close_weak_asap`.
9942 ///
9943 /// If sent, this message must be before
9944 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
9945 ///
9946 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
9947 /// send this message before `WaitForAllBuffersAllocated`, or a parent
9948 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
9949 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
9950 /// trigger buffer collection failure.
9951 ///
9952 /// This message is necessary because weak sysmem VMOs have not always been
9953 /// a thing, so older clients are not aware of the need to pay attention to
9954 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
9955 /// sysmem weak VMO handles asap. By having this message and requiring
9956 /// participants to indicate their acceptance of this aspect of the overall
9957 /// protocol, we avoid situations where an older client is delivered a weak
9958 /// VMO without any way for sysmem to get that VMO to close quickly later
9959 /// (and on a per-buffer basis).
9960 ///
9961 /// A participant that doesn't handle `close_weak_asap` and also doesn't
9962 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
9963 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
9964 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
9965 /// same participant has a child/delegate which does retrieve VMOs, that
9966 /// child/delegate will need to send `SetWeakOk` before
9967 /// `WaitForAllBuffersAllocated`.
9968 ///
9969 /// + request `for_child_nodes_also` If present and true, this means direct
9970 /// child nodes of this node created after this message plus all
9971 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
9972 /// those nodes. Any child node of this node that was created before this
9973 /// message is not included. This setting is "sticky" in the sense that a
9974 /// subsequent `SetWeakOk` without this bool set to true does not reset
9975 /// the server-side bool. If this creates a problem for a participant, a
9976 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
9977 /// tokens instead, as appropriate. A participant should only set
9978 /// `for_child_nodes_also` true if the participant can really promise to
9979 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
9980 /// weak VMO handles held by participants holding the corresponding child
9981 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
9982 /// which are using sysmem(1) can be weak, despite the clients of those
9983 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
9984 /// direct way to find out about `close_weak_asap`. This only applies to
9985 /// descendents of this `Node` which are using sysmem(1), not to this
9986 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
9987 /// token, which will fail allocation unless an ancestor of this `Node`
9988 /// specified `for_child_nodes_also` true.
9989 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
9990 self.client.send::<NodeSetWeakOkRequest>(
9991 &mut payload,
9992 0x38a44fc4d7724be9,
9993 fidl::encoding::DynamicFlags::FLEXIBLE,
9994 )
9995 }
9996
9997 /// The server_end will be closed after this `Node` and any child nodes have
9998 /// have released their buffer counts, making those counts available for
9999 /// reservation by a different `Node` via
10000 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
10001 ///
10002 /// The `Node` buffer counts may not be released until the entire tree of
10003 /// `Node`(s) is closed or failed, because
10004 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
10005 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
10006 /// `Node` buffer counts remain reserved until the orphaned node is later
10007 /// cleaned up.
10008 ///
10009 /// If the `Node` exceeds a fairly large number of attached eventpair server
10010 /// ends, a log message will indicate this and the `Node` (and the
10011 /// appropriate) sub-tree will fail.
10012 ///
10013 /// The `server_end` will remain open when
10014 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
10015 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
10016 /// [`fuchsia.sysmem2/BufferCollection`].
10017 ///
10018 /// This message can also be used with a
10019 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
10020 pub fn r#attach_node_tracking(
10021 &self,
10022 mut payload: NodeAttachNodeTrackingRequest,
10023 ) -> Result<(), fidl::Error> {
10024 self.client.send::<NodeAttachNodeTrackingRequest>(
10025 &mut payload,
10026 0x3f22f2a293d3cdac,
10027 fidl::encoding::DynamicFlags::FLEXIBLE,
10028 )
10029 }
10030
10031 /// Create a child [`fuchsia.sysmem2/BufferCollectionToken`]. Only one child
10032 /// (including its children) will be selected during allocation (or logical
10033 /// allocation).
10034 ///
10035 /// Before passing the client end of this token to
10036 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], completion of
10037 /// [`fuchsia.sysmem2/Node.Sync`] after
10038 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] is required.
10039 /// Or the client can use
10040 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`] which
10041 /// essentially includes the `Sync`.
10042 ///
10043 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
10044 /// fail the group's subtree and close the connection.
10045 ///
10046 /// After all children have been created, send AllChildrenPresent.
10047 ///
10048 /// + request `token_request` The server end of the new token channel.
10049 /// + request `rights_attenuation_mask` If ZX_RIGHT_SAME_RIGHTS, the created
10050 /// token allows the holder to get the same rights to buffers as the
10051 /// parent token (of the group) had. When the value isn't
10052 /// ZX_RIGHT_SAME_RIGHTS, the value is interpretted as a bitmask with 0
10053 /// bits ensuring those rights are attentuated, so 0xFFFFFFFF is a synonym
10054 /// for ZX_RIGHT_SAME_RIGHTS. The value 0 is not allowed and intentionally
10055 /// causes subtree failure.
10056 pub fn r#create_child(
10057 &self,
10058 mut payload: BufferCollectionTokenGroupCreateChildRequest,
10059 ) -> Result<(), fidl::Error> {
10060 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
10061 &mut payload,
10062 0x41a0075d419f30c5,
10063 fidl::encoding::DynamicFlags::FLEXIBLE,
10064 )
10065 }
10066
10067 /// Create 1 or more child tokens at once, synchronously. In contrast to
10068 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`], no
10069 /// [`fuchsia.sysmem2/Node.Sync`] is required before passing the client end
10070 /// of a returned token to
10071 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`].
10072 ///
10073 /// The lower-index child tokens are higher priority (attempted sooner) than
10074 /// higher-index child tokens.
10075 ///
10076 /// As per all child tokens, successful aggregation will choose exactly one
10077 /// child among all created children (across all children created across
10078 /// potentially multiple calls to
10079 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] and
10080 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`]).
10081 ///
10082 /// The maximum permissible total number of children per group, and total
10083 /// number of nodes in an overall tree (from the root) are capped to limits
10084 /// which are not configurable via these protocols.
10085 ///
10086 /// Sending CreateChildrenSync after AllChildrenPresent is not permitted;
10087 /// this will fail the group's subtree and close the connection.
10088 ///
10089 /// After all children have been created, send AllChildrenPresent.
10090 ///
10091 /// + request `rights_attentuation_masks` The size of the
10092 /// `rights_attentuation_masks` determines the number of created child
10093 /// tokens. The value ZX_RIGHT_SAME_RIGHTS doesn't attenuate any rights.
10094 /// The value 0xFFFFFFFF is a synonym for ZX_RIGHT_SAME_RIGHTS. For any
10095 /// other value, each 0 bit in the mask attenuates that right.
10096 /// - response `tokens` The created child tokens.
10097 pub fn r#create_children_sync(
10098 &self,
10099 mut payload: &BufferCollectionTokenGroupCreateChildrenSyncRequest,
10100 ___deadline: zx::MonotonicInstant,
10101 ) -> Result<BufferCollectionTokenGroupCreateChildrenSyncResponse, fidl::Error> {
10102 let _response = self.client.send_query::<
10103 BufferCollectionTokenGroupCreateChildrenSyncRequest,
10104 fidl::encoding::FlexibleType<BufferCollectionTokenGroupCreateChildrenSyncResponse>,
10105 BufferCollectionTokenGroupMarker,
10106 >(
10107 payload,
10108 0x15dea448c536070a,
10109 fidl::encoding::DynamicFlags::FLEXIBLE,
10110 ___deadline,
10111 )?
10112 .into_result::<BufferCollectionTokenGroupMarker>("create_children_sync")?;
10113 Ok(_response)
10114 }
10115
10116 /// Indicate that no more children will be created.
10117 ///
10118 /// After creating all children, the client should send
10119 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent`] to
10120 /// inform sysmem that no more children will be created, so that sysmem can
10121 /// know when it's ok to start aggregating constraints.
10122 ///
10123 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
10124 /// fail the group's subtree and close the connection.
10125 ///
10126 /// If [`fuchsia.sysmem2/Node.Release`] is to be sent, it should be sent
10127 /// after `AllChildrenPresent`, else failure of the group's subtree will be
10128 /// triggered. This is intentionally not analogous to how `Release` without
10129 /// prior [`fuchsia.sysmem2/BufferCollection.SetConstraints`] doesn't cause
10130 /// subtree failure.
10131 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
10132 self.client.send::<fidl::encoding::EmptyPayload>(
10133 (),
10134 0x5c327e4a23391312,
10135 fidl::encoding::DynamicFlags::FLEXIBLE,
10136 )
10137 }
10138}
10139
10140#[cfg(target_os = "fuchsia")]
10141impl From<BufferCollectionTokenGroupSynchronousProxy> for zx::NullableHandle {
10142 fn from(value: BufferCollectionTokenGroupSynchronousProxy) -> Self {
10143 value.into_channel().into()
10144 }
10145}
10146
10147#[cfg(target_os = "fuchsia")]
10148impl From<fidl::Channel> for BufferCollectionTokenGroupSynchronousProxy {
10149 fn from(value: fidl::Channel) -> Self {
10150 Self::new(value)
10151 }
10152}
10153
10154#[cfg(target_os = "fuchsia")]
10155impl fidl::endpoints::FromClient for BufferCollectionTokenGroupSynchronousProxy {
10156 type Protocol = BufferCollectionTokenGroupMarker;
10157
10158 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionTokenGroupMarker>) -> Self {
10159 Self::new(value.into_channel())
10160 }
10161}
10162
10163#[derive(Debug, Clone)]
10164pub struct BufferCollectionTokenGroupProxy {
10165 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
10166}
10167
10168impl fidl::endpoints::Proxy for BufferCollectionTokenGroupProxy {
10169 type Protocol = BufferCollectionTokenGroupMarker;
10170
10171 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
10172 Self::new(inner)
10173 }
10174
10175 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
10176 self.client.into_channel().map_err(|client| Self { client })
10177 }
10178
10179 fn as_channel(&self) -> &::fidl::AsyncChannel {
10180 self.client.as_channel()
10181 }
10182}
10183
10184impl BufferCollectionTokenGroupProxy {
10185 /// Create a new Proxy for fuchsia.sysmem2/BufferCollectionTokenGroup.
10186 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
10187 let protocol_name =
10188 <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
10189 Self { client: fidl::client::Client::new(channel, protocol_name) }
10190 }
10191
10192 /// Get a Stream of events from the remote end of the protocol.
10193 ///
10194 /// # Panics
10195 ///
10196 /// Panics if the event stream was already taken.
10197 pub fn take_event_stream(&self) -> BufferCollectionTokenGroupEventStream {
10198 BufferCollectionTokenGroupEventStream { event_receiver: self.client.take_event_receiver() }
10199 }
10200
10201 /// Ensure that previous messages have been received server side. This is
10202 /// particularly useful after previous messages that created new tokens,
10203 /// because a token must be known to the sysmem server before sending the
10204 /// token to another participant.
10205 ///
10206 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
10207 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
10208 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
10209 /// to mitigate the possibility of a hostile/fake
10210 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
10211 /// Another way is to pass the token to
10212 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
10213 /// the token as part of exchanging it for a
10214 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
10215 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
10216 /// of stalling.
10217 ///
10218 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
10219 /// and then starting and completing a `Sync`, it's then safe to send the
10220 /// `BufferCollectionToken` client ends to other participants knowing the
10221 /// server will recognize the tokens when they're sent by the other
10222 /// participants to sysmem in a
10223 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
10224 /// efficient way to create tokens while avoiding unnecessary round trips.
10225 ///
10226 /// Other options include waiting for each
10227 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
10228 /// individually (using separate call to `Sync` after each), or calling
10229 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
10230 /// converted to a `BufferCollection` via
10231 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
10232 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
10233 /// the sync step and can create multiple tokens at once.
10234 pub fn r#sync(
10235 &self,
10236 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
10237 BufferCollectionTokenGroupProxyInterface::r#sync(self)
10238 }
10239
10240 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
10241 ///
10242 /// Normally a participant will convert a `BufferCollectionToken` into a
10243 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
10244 /// `Release` via the token (and then close the channel immediately or
10245 /// shortly later in response to server closing the server end), which
10246 /// avoids causing buffer collection failure. Without a prior `Release`,
10247 /// closing the `BufferCollectionToken` client end will cause buffer
10248 /// collection failure.
10249 ///
10250 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
10251 ///
10252 /// By default the server handles unexpected closure of a
10253 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
10254 /// first) by failing the buffer collection. Partly this is to expedite
10255 /// closing VMO handles to reclaim memory when any participant fails. If a
10256 /// participant would like to cleanly close a `BufferCollection` without
10257 /// causing buffer collection failure, the participant can send `Release`
10258 /// before closing the `BufferCollection` client end. The `Release` can
10259 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
10260 /// buffer collection won't require constraints from this node in order to
10261 /// allocate. If after `SetConstraints`, the constraints are retained and
10262 /// aggregated, despite the lack of `BufferCollection` connection at the
10263 /// time of constraints aggregation.
10264 ///
10265 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
10266 ///
10267 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
10268 /// end (without `Release` first) will trigger failure of the buffer
10269 /// collection. To close a `BufferCollectionTokenGroup` channel without
10270 /// failing the buffer collection, ensure that AllChildrenPresent() has been
10271 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
10272 /// client end.
10273 ///
10274 /// If `Release` occurs before
10275 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
10276 /// buffer collection will fail (triggered by reception of `Release` without
10277 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
10278 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
10279 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
10280 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
10281 /// close requires `AllChildrenPresent` (if not already sent), then
10282 /// `Release`, then close client end.
10283 ///
10284 /// If `Release` occurs after `AllChildrenPresent`, the children and all
10285 /// their constraints remain intact (just as they would if the
10286 /// `BufferCollectionTokenGroup` channel had remained open), and the client
10287 /// end close doesn't trigger buffer collection failure.
10288 ///
10289 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
10290 ///
10291 /// For brevity, the per-channel-protocol paragraphs above ignore the
10292 /// separate failure domain created by
10293 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
10294 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
10295 /// unexpectedly closes (without `Release` first) and that client end is
10296 /// under a failure domain, instead of failing the whole buffer collection,
10297 /// the failure domain is failed, but the buffer collection itself is
10298 /// isolated from failure of the failure domain. Such failure domains can be
10299 /// nested, in which case only the inner-most failure domain in which the
10300 /// `Node` resides fails.
10301 pub fn r#release(&self) -> Result<(), fidl::Error> {
10302 BufferCollectionTokenGroupProxyInterface::r#release(self)
10303 }
10304
10305 /// Set a name for VMOs in this buffer collection.
10306 ///
10307 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
10308 /// will be truncated to fit. The name of the vmo will be suffixed with the
10309 /// buffer index within the collection (if the suffix fits within
10310 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
10311 /// listed in the inspect data.
10312 ///
10313 /// The name only affects VMOs allocated after the name is set; this call
10314 /// does not rename existing VMOs. If multiple clients set different names
10315 /// then the larger priority value will win. Setting a new name with the
10316 /// same priority as a prior name doesn't change the name.
10317 ///
10318 /// All table fields are currently required.
10319 ///
10320 /// + request `priority` The name is only set if this is the first `SetName`
10321 /// or if `priority` is greater than any previous `priority` value in
10322 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
10323 /// + request `name` The name for VMOs created under this buffer collection.
10324 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
10325 BufferCollectionTokenGroupProxyInterface::r#set_name(self, payload)
10326 }
10327
10328 /// Set information about the current client that can be used by sysmem to
10329 /// help diagnose leaking memory and allocation stalls waiting for a
10330 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
10331 ///
10332 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
10333 /// `Node`(s) derived from this `Node`, unless overriden by
10334 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
10335 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
10336 ///
10337 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
10338 /// `Allocator` is the most efficient way to ensure that all
10339 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
10340 /// set, and is also more efficient than separately sending the same debug
10341 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
10342 /// created [`fuchsia.sysmem2/Node`].
10343 ///
10344 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
10345 /// indicate which client is closing their channel first, leading to subtree
10346 /// failure (which can be normal if the purpose of the subtree is over, but
10347 /// if happening earlier than expected, the client-channel-specific name can
10348 /// help diagnose where the failure is first coming from, from sysmem's
10349 /// point of view).
10350 ///
10351 /// All table fields are currently required.
10352 ///
10353 /// + request `name` This can be an arbitrary string, but the current
10354 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
10355 /// + request `id` This can be an arbitrary id, but the current process ID
10356 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
10357 pub fn r#set_debug_client_info(
10358 &self,
10359 mut payload: &NodeSetDebugClientInfoRequest,
10360 ) -> Result<(), fidl::Error> {
10361 BufferCollectionTokenGroupProxyInterface::r#set_debug_client_info(self, payload)
10362 }
10363
10364 /// Sysmem logs a warning if sysmem hasn't seen
10365 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
10366 /// within 5 seconds after creation of a new collection.
10367 ///
10368 /// Clients can call this method to change when the log is printed. If
10369 /// multiple client set the deadline, it's unspecified which deadline will
10370 /// take effect.
10371 ///
10372 /// In most cases the default works well.
10373 ///
10374 /// All table fields are currently required.
10375 ///
10376 /// + request `deadline` The time at which sysmem will start trying to log
10377 /// the warning, unless all constraints are with sysmem by then.
10378 pub fn r#set_debug_timeout_log_deadline(
10379 &self,
10380 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
10381 ) -> Result<(), fidl::Error> {
10382 BufferCollectionTokenGroupProxyInterface::r#set_debug_timeout_log_deadline(self, payload)
10383 }
10384
10385 /// This enables verbose logging for the buffer collection.
10386 ///
10387 /// Verbose logging includes constraints set via
10388 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
10389 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
10390 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
10391 /// the tree of `Node`(s).
10392 ///
10393 /// Normally sysmem prints only a single line complaint when aggregation
10394 /// fails, with just the specific detailed reason that aggregation failed,
10395 /// with little surrounding context. While this is often enough to diagnose
10396 /// a problem if only a small change was made and everything was working
10397 /// before the small change, it's often not particularly helpful for getting
10398 /// a new buffer collection to work for the first time. Especially with
10399 /// more complex trees of nodes, involving things like
10400 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
10401 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
10402 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
10403 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
10404 /// looks like and why it's failing a logical allocation, or why a tree or
10405 /// subtree is failing sooner than expected.
10406 ///
10407 /// The intent of the extra logging is to be acceptable from a performance
10408 /// point of view, under the assumption that verbose logging is only enabled
10409 /// on a low number of buffer collections. If we're not tracking down a bug,
10410 /// we shouldn't send this message.
10411 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
10412 BufferCollectionTokenGroupProxyInterface::r#set_verbose_logging(self)
10413 }
10414
10415 /// This gets a handle that can be used as a parameter to
10416 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
10417 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
10418 /// client obtained this handle from this `Node`.
10419 ///
10420 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
10421 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
10422 /// despite the two calls typically being on different channels.
10423 ///
10424 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
10425 ///
10426 /// All table fields are currently required.
10427 ///
10428 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
10429 /// different `Node` channel, to prove that the client obtained the handle
10430 /// from this `Node`.
10431 pub fn r#get_node_ref(
10432 &self,
10433 ) -> fidl::client::QueryResponseFut<
10434 NodeGetNodeRefResponse,
10435 fidl::encoding::DefaultFuchsiaResourceDialect,
10436 > {
10437 BufferCollectionTokenGroupProxyInterface::r#get_node_ref(self)
10438 }
10439
10440 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
10441 /// rooted at a different child token of a common parent
10442 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
10443 /// passed-in `node_ref`.
10444 ///
10445 /// This call is for assisting with admission control de-duplication, and
10446 /// with debugging.
10447 ///
10448 /// The `node_ref` must be obtained using
10449 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
10450 ///
10451 /// The `node_ref` can be a duplicated handle; it's not necessary to call
10452 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
10453 ///
10454 /// If a calling token may not actually be a valid token at all due to a
10455 /// potentially hostile/untrusted provider of the token, call
10456 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
10457 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
10458 /// never responds due to a calling token not being a real token (not really
10459 /// talking to sysmem). Another option is to call
10460 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
10461 /// which also validates the token along with converting it to a
10462 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
10463 ///
10464 /// All table fields are currently required.
10465 ///
10466 /// - response `is_alternate`
10467 /// - true: The first parent node in common between the calling node and
10468 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
10469 /// that the calling `Node` and the `node_ref` `Node` will not have both
10470 /// their constraints apply - rather sysmem will choose one or the other
10471 /// of the constraints - never both. This is because only one child of
10472 /// a `BufferCollectionTokenGroup` is selected during logical
10473 /// allocation, with only that one child's subtree contributing to
10474 /// constraints aggregation.
10475 /// - false: The first parent node in common between the calling `Node`
10476 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
10477 /// Currently, this means the first parent node in common is a
10478 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
10479 /// `Release`ed). This means that the calling `Node` and the `node_ref`
10480 /// `Node` may have both their constraints apply during constraints
10481 /// aggregation of the logical allocation, if both `Node`(s) are
10482 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
10483 /// this case, there is no `BufferCollectionTokenGroup` that will
10484 /// directly prevent the two `Node`(s) from both being selected and
10485 /// their constraints both aggregated, but even when false, one or both
10486 /// `Node`(s) may still be eliminated from consideration if one or both
10487 /// `Node`(s) has a direct or indirect parent
10488 /// `BufferCollectionTokenGroup` which selects a child subtree other
10489 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
10490 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
10491 /// associated with the same buffer collection as the calling `Node`.
10492 /// Another reason for this error is if the `node_ref` is an
10493 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
10494 /// a real `node_ref` obtained from `GetNodeRef`.
10495 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
10496 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
10497 /// the needed rights expected on a real `node_ref`.
10498 /// * No other failing status codes are returned by this call. However,
10499 /// sysmem may add additional codes in future, so the client should have
10500 /// sensible default handling for any failing status code.
10501 pub fn r#is_alternate_for(
10502 &self,
10503 mut payload: NodeIsAlternateForRequest,
10504 ) -> fidl::client::QueryResponseFut<
10505 NodeIsAlternateForResult,
10506 fidl::encoding::DefaultFuchsiaResourceDialect,
10507 > {
10508 BufferCollectionTokenGroupProxyInterface::r#is_alternate_for(self, payload)
10509 }
10510
10511 /// Get the buffer collection ID. This ID is also available from
10512 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
10513 /// within the collection).
10514 ///
10515 /// This call is mainly useful in situations where we can't convey a
10516 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
10517 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
10518 /// handle, which can be joined back up with a `BufferCollection` client end
10519 /// that was created via a different path. Prefer to convey a
10520 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
10521 ///
10522 /// Trusting a `buffer_collection_id` value from a source other than sysmem
10523 /// is analogous to trusting a koid value from a source other than zircon.
10524 /// Both should be avoided unless really necessary, and both require
10525 /// caution. In some situations it may be reasonable to refer to a
10526 /// pre-established `BufferCollection` by `buffer_collection_id` via a
10527 /// protocol for efficiency reasons, but an incoming value purporting to be
10528 /// a `buffer_collection_id` is not sufficient alone to justify granting the
10529 /// sender of the `buffer_collection_id` any capability. The sender must
10530 /// first prove to a receiver that the sender has/had a VMO or has/had a
10531 /// `BufferCollectionToken` to the same collection by sending a handle that
10532 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
10533 /// `buffer_collection_id` value. The receiver should take care to avoid
10534 /// assuming that a sender had a `BufferCollectionToken` in cases where the
10535 /// sender has only proven that the sender had a VMO.
10536 ///
10537 /// - response `buffer_collection_id` This ID is unique per buffer
10538 /// collection per boot. Each buffer is uniquely identified by the
10539 /// `buffer_collection_id` and `buffer_index` together.
10540 pub fn r#get_buffer_collection_id(
10541 &self,
10542 ) -> fidl::client::QueryResponseFut<
10543 NodeGetBufferCollectionIdResponse,
10544 fidl::encoding::DefaultFuchsiaResourceDialect,
10545 > {
10546 BufferCollectionTokenGroupProxyInterface::r#get_buffer_collection_id(self)
10547 }
10548
10549 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
10550 /// created after this message to weak, which means that a client's `Node`
10551 /// client end (or a child created after this message) is not alone
10552 /// sufficient to keep allocated VMOs alive.
10553 ///
10554 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
10555 /// `close_weak_asap`.
10556 ///
10557 /// This message is only permitted before the `Node` becomes ready for
10558 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
10559 /// * `BufferCollectionToken`: any time
10560 /// * `BufferCollection`: before `SetConstraints`
10561 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
10562 ///
10563 /// Currently, no conversion from strong `Node` to weak `Node` after ready
10564 /// for allocation is provided, but a client can simulate that by creating
10565 /// an additional `Node` before allocation and setting that additional
10566 /// `Node` to weak, and then potentially at some point later sending
10567 /// `Release` and closing the client end of the client's strong `Node`, but
10568 /// keeping the client's weak `Node`.
10569 ///
10570 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
10571 /// collection failure (all `Node` client end(s) will see
10572 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
10573 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
10574 /// this situation until all `Node`(s) are ready for allocation. For initial
10575 /// allocation to succeed, at least one strong `Node` is required to exist
10576 /// at allocation time, but after that client receives VMO handles, that
10577 /// client can `BufferCollection.Release` and close the client end without
10578 /// causing this type of failure.
10579 ///
10580 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
10581 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
10582 /// separately as appropriate.
10583 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
10584 BufferCollectionTokenGroupProxyInterface::r#set_weak(self)
10585 }
10586
10587 /// This indicates to sysmem that the client is prepared to pay attention to
10588 /// `close_weak_asap`.
10589 ///
10590 /// If sent, this message must be before
10591 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
10592 ///
10593 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
10594 /// send this message before `WaitForAllBuffersAllocated`, or a parent
10595 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
10596 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
10597 /// trigger buffer collection failure.
10598 ///
10599 /// This message is necessary because weak sysmem VMOs have not always been
10600 /// a thing, so older clients are not aware of the need to pay attention to
10601 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
10602 /// sysmem weak VMO handles asap. By having this message and requiring
10603 /// participants to indicate their acceptance of this aspect of the overall
10604 /// protocol, we avoid situations where an older client is delivered a weak
10605 /// VMO without any way for sysmem to get that VMO to close quickly later
10606 /// (and on a per-buffer basis).
10607 ///
10608 /// A participant that doesn't handle `close_weak_asap` and also doesn't
10609 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
10610 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
10611 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
10612 /// same participant has a child/delegate which does retrieve VMOs, that
10613 /// child/delegate will need to send `SetWeakOk` before
10614 /// `WaitForAllBuffersAllocated`.
10615 ///
10616 /// + request `for_child_nodes_also` If present and true, this means direct
10617 /// child nodes of this node created after this message plus all
10618 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
10619 /// those nodes. Any child node of this node that was created before this
10620 /// message is not included. This setting is "sticky" in the sense that a
10621 /// subsequent `SetWeakOk` without this bool set to true does not reset
10622 /// the server-side bool. If this creates a problem for a participant, a
10623 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
10624 /// tokens instead, as appropriate. A participant should only set
10625 /// `for_child_nodes_also` true if the participant can really promise to
10626 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
10627 /// weak VMO handles held by participants holding the corresponding child
10628 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
10629 /// which are using sysmem(1) can be weak, despite the clients of those
10630 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
10631 /// direct way to find out about `close_weak_asap`. This only applies to
10632 /// descendents of this `Node` which are using sysmem(1), not to this
10633 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
10634 /// token, which will fail allocation unless an ancestor of this `Node`
10635 /// specified `for_child_nodes_also` true.
10636 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
10637 BufferCollectionTokenGroupProxyInterface::r#set_weak_ok(self, payload)
10638 }
10639
10640 /// The server_end will be closed after this `Node` and any child nodes have
10641 /// have released their buffer counts, making those counts available for
10642 /// reservation by a different `Node` via
10643 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
10644 ///
10645 /// The `Node` buffer counts may not be released until the entire tree of
10646 /// `Node`(s) is closed or failed, because
10647 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
10648 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
10649 /// `Node` buffer counts remain reserved until the orphaned node is later
10650 /// cleaned up.
10651 ///
10652 /// If the `Node` exceeds a fairly large number of attached eventpair server
10653 /// ends, a log message will indicate this and the `Node` (and the
10654 /// appropriate) sub-tree will fail.
10655 ///
10656 /// The `server_end` will remain open when
10657 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
10658 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
10659 /// [`fuchsia.sysmem2/BufferCollection`].
10660 ///
10661 /// This message can also be used with a
10662 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
10663 pub fn r#attach_node_tracking(
10664 &self,
10665 mut payload: NodeAttachNodeTrackingRequest,
10666 ) -> Result<(), fidl::Error> {
10667 BufferCollectionTokenGroupProxyInterface::r#attach_node_tracking(self, payload)
10668 }
10669
10670 /// Create a child [`fuchsia.sysmem2/BufferCollectionToken`]. Only one child
10671 /// (including its children) will be selected during allocation (or logical
10672 /// allocation).
10673 ///
10674 /// Before passing the client end of this token to
10675 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], completion of
10676 /// [`fuchsia.sysmem2/Node.Sync`] after
10677 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] is required.
10678 /// Or the client can use
10679 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`] which
10680 /// essentially includes the `Sync`.
10681 ///
10682 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
10683 /// fail the group's subtree and close the connection.
10684 ///
10685 /// After all children have been created, send AllChildrenPresent.
10686 ///
10687 /// + request `token_request` The server end of the new token channel.
10688 /// + request `rights_attenuation_mask` If ZX_RIGHT_SAME_RIGHTS, the created
10689 /// token allows the holder to get the same rights to buffers as the
10690 /// parent token (of the group) had. When the value isn't
10691 /// ZX_RIGHT_SAME_RIGHTS, the value is interpretted as a bitmask with 0
10692 /// bits ensuring those rights are attentuated, so 0xFFFFFFFF is a synonym
10693 /// for ZX_RIGHT_SAME_RIGHTS. The value 0 is not allowed and intentionally
10694 /// causes subtree failure.
10695 pub fn r#create_child(
10696 &self,
10697 mut payload: BufferCollectionTokenGroupCreateChildRequest,
10698 ) -> Result<(), fidl::Error> {
10699 BufferCollectionTokenGroupProxyInterface::r#create_child(self, payload)
10700 }
10701
10702 /// Create 1 or more child tokens at once, synchronously. In contrast to
10703 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`], no
10704 /// [`fuchsia.sysmem2/Node.Sync`] is required before passing the client end
10705 /// of a returned token to
10706 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`].
10707 ///
10708 /// The lower-index child tokens are higher priority (attempted sooner) than
10709 /// higher-index child tokens.
10710 ///
10711 /// As per all child tokens, successful aggregation will choose exactly one
10712 /// child among all created children (across all children created across
10713 /// potentially multiple calls to
10714 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] and
10715 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`]).
10716 ///
10717 /// The maximum permissible total number of children per group, and total
10718 /// number of nodes in an overall tree (from the root) are capped to limits
10719 /// which are not configurable via these protocols.
10720 ///
10721 /// Sending CreateChildrenSync after AllChildrenPresent is not permitted;
10722 /// this will fail the group's subtree and close the connection.
10723 ///
10724 /// After all children have been created, send AllChildrenPresent.
10725 ///
10726 /// + request `rights_attentuation_masks` The size of the
10727 /// `rights_attentuation_masks` determines the number of created child
10728 /// tokens. The value ZX_RIGHT_SAME_RIGHTS doesn't attenuate any rights.
10729 /// The value 0xFFFFFFFF is a synonym for ZX_RIGHT_SAME_RIGHTS. For any
10730 /// other value, each 0 bit in the mask attenuates that right.
10731 /// - response `tokens` The created child tokens.
10732 pub fn r#create_children_sync(
10733 &self,
10734 mut payload: &BufferCollectionTokenGroupCreateChildrenSyncRequest,
10735 ) -> fidl::client::QueryResponseFut<
10736 BufferCollectionTokenGroupCreateChildrenSyncResponse,
10737 fidl::encoding::DefaultFuchsiaResourceDialect,
10738 > {
10739 BufferCollectionTokenGroupProxyInterface::r#create_children_sync(self, payload)
10740 }
10741
10742 /// Indicate that no more children will be created.
10743 ///
10744 /// After creating all children, the client should send
10745 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent`] to
10746 /// inform sysmem that no more children will be created, so that sysmem can
10747 /// know when it's ok to start aggregating constraints.
10748 ///
10749 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
10750 /// fail the group's subtree and close the connection.
10751 ///
10752 /// If [`fuchsia.sysmem2/Node.Release`] is to be sent, it should be sent
10753 /// after `AllChildrenPresent`, else failure of the group's subtree will be
10754 /// triggered. This is intentionally not analogous to how `Release` without
10755 /// prior [`fuchsia.sysmem2/BufferCollection.SetConstraints`] doesn't cause
10756 /// subtree failure.
10757 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
10758 BufferCollectionTokenGroupProxyInterface::r#all_children_present(self)
10759 }
10760}
10761
10762impl BufferCollectionTokenGroupProxyInterface for BufferCollectionTokenGroupProxy {
10763 type SyncResponseFut =
10764 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
10765 fn r#sync(&self) -> Self::SyncResponseFut {
10766 fn _decode(
10767 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10768 ) -> Result<(), fidl::Error> {
10769 let _response = fidl::client::decode_transaction_body::<
10770 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
10771 fidl::encoding::DefaultFuchsiaResourceDialect,
10772 0x11ac2555cf575b54,
10773 >(_buf?)?
10774 .into_result::<BufferCollectionTokenGroupMarker>("sync")?;
10775 Ok(_response)
10776 }
10777 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
10778 (),
10779 0x11ac2555cf575b54,
10780 fidl::encoding::DynamicFlags::FLEXIBLE,
10781 _decode,
10782 )
10783 }
10784
10785 fn r#release(&self) -> Result<(), fidl::Error> {
10786 self.client.send::<fidl::encoding::EmptyPayload>(
10787 (),
10788 0x6a5cae7d6d6e04c6,
10789 fidl::encoding::DynamicFlags::FLEXIBLE,
10790 )
10791 }
10792
10793 fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
10794 self.client.send::<NodeSetNameRequest>(
10795 payload,
10796 0xb41f1624f48c1e9,
10797 fidl::encoding::DynamicFlags::FLEXIBLE,
10798 )
10799 }
10800
10801 fn r#set_debug_client_info(
10802 &self,
10803 mut payload: &NodeSetDebugClientInfoRequest,
10804 ) -> Result<(), fidl::Error> {
10805 self.client.send::<NodeSetDebugClientInfoRequest>(
10806 payload,
10807 0x5cde8914608d99b1,
10808 fidl::encoding::DynamicFlags::FLEXIBLE,
10809 )
10810 }
10811
10812 fn r#set_debug_timeout_log_deadline(
10813 &self,
10814 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
10815 ) -> Result<(), fidl::Error> {
10816 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
10817 payload,
10818 0x716b0af13d5c0806,
10819 fidl::encoding::DynamicFlags::FLEXIBLE,
10820 )
10821 }
10822
10823 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
10824 self.client.send::<fidl::encoding::EmptyPayload>(
10825 (),
10826 0x5209c77415b4dfad,
10827 fidl::encoding::DynamicFlags::FLEXIBLE,
10828 )
10829 }
10830
10831 type GetNodeRefResponseFut = fidl::client::QueryResponseFut<
10832 NodeGetNodeRefResponse,
10833 fidl::encoding::DefaultFuchsiaResourceDialect,
10834 >;
10835 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
10836 fn _decode(
10837 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10838 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
10839 let _response = fidl::client::decode_transaction_body::<
10840 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
10841 fidl::encoding::DefaultFuchsiaResourceDialect,
10842 0x5b3d0e51614df053,
10843 >(_buf?)?
10844 .into_result::<BufferCollectionTokenGroupMarker>("get_node_ref")?;
10845 Ok(_response)
10846 }
10847 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
10848 (),
10849 0x5b3d0e51614df053,
10850 fidl::encoding::DynamicFlags::FLEXIBLE,
10851 _decode,
10852 )
10853 }
10854
10855 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
10856 NodeIsAlternateForResult,
10857 fidl::encoding::DefaultFuchsiaResourceDialect,
10858 >;
10859 fn r#is_alternate_for(
10860 &self,
10861 mut payload: NodeIsAlternateForRequest,
10862 ) -> Self::IsAlternateForResponseFut {
10863 fn _decode(
10864 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10865 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
10866 let _response = fidl::client::decode_transaction_body::<
10867 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
10868 fidl::encoding::DefaultFuchsiaResourceDialect,
10869 0x3a58e00157e0825,
10870 >(_buf?)?
10871 .into_result::<BufferCollectionTokenGroupMarker>("is_alternate_for")?;
10872 Ok(_response.map(|x| x))
10873 }
10874 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
10875 &mut payload,
10876 0x3a58e00157e0825,
10877 fidl::encoding::DynamicFlags::FLEXIBLE,
10878 _decode,
10879 )
10880 }
10881
10882 type GetBufferCollectionIdResponseFut = fidl::client::QueryResponseFut<
10883 NodeGetBufferCollectionIdResponse,
10884 fidl::encoding::DefaultFuchsiaResourceDialect,
10885 >;
10886 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut {
10887 fn _decode(
10888 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10889 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
10890 let _response = fidl::client::decode_transaction_body::<
10891 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
10892 fidl::encoding::DefaultFuchsiaResourceDialect,
10893 0x77d19a494b78ba8c,
10894 >(_buf?)?
10895 .into_result::<BufferCollectionTokenGroupMarker>("get_buffer_collection_id")?;
10896 Ok(_response)
10897 }
10898 self.client.send_query_and_decode::<
10899 fidl::encoding::EmptyPayload,
10900 NodeGetBufferCollectionIdResponse,
10901 >(
10902 (),
10903 0x77d19a494b78ba8c,
10904 fidl::encoding::DynamicFlags::FLEXIBLE,
10905 _decode,
10906 )
10907 }
10908
10909 fn r#set_weak(&self) -> Result<(), fidl::Error> {
10910 self.client.send::<fidl::encoding::EmptyPayload>(
10911 (),
10912 0x22dd3ea514eeffe1,
10913 fidl::encoding::DynamicFlags::FLEXIBLE,
10914 )
10915 }
10916
10917 fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
10918 self.client.send::<NodeSetWeakOkRequest>(
10919 &mut payload,
10920 0x38a44fc4d7724be9,
10921 fidl::encoding::DynamicFlags::FLEXIBLE,
10922 )
10923 }
10924
10925 fn r#attach_node_tracking(
10926 &self,
10927 mut payload: NodeAttachNodeTrackingRequest,
10928 ) -> Result<(), fidl::Error> {
10929 self.client.send::<NodeAttachNodeTrackingRequest>(
10930 &mut payload,
10931 0x3f22f2a293d3cdac,
10932 fidl::encoding::DynamicFlags::FLEXIBLE,
10933 )
10934 }
10935
10936 fn r#create_child(
10937 &self,
10938 mut payload: BufferCollectionTokenGroupCreateChildRequest,
10939 ) -> Result<(), fidl::Error> {
10940 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
10941 &mut payload,
10942 0x41a0075d419f30c5,
10943 fidl::encoding::DynamicFlags::FLEXIBLE,
10944 )
10945 }
10946
10947 type CreateChildrenSyncResponseFut = fidl::client::QueryResponseFut<
10948 BufferCollectionTokenGroupCreateChildrenSyncResponse,
10949 fidl::encoding::DefaultFuchsiaResourceDialect,
10950 >;
10951 fn r#create_children_sync(
10952 &self,
10953 mut payload: &BufferCollectionTokenGroupCreateChildrenSyncRequest,
10954 ) -> Self::CreateChildrenSyncResponseFut {
10955 fn _decode(
10956 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10957 ) -> Result<BufferCollectionTokenGroupCreateChildrenSyncResponse, fidl::Error> {
10958 let _response = fidl::client::decode_transaction_body::<
10959 fidl::encoding::FlexibleType<BufferCollectionTokenGroupCreateChildrenSyncResponse>,
10960 fidl::encoding::DefaultFuchsiaResourceDialect,
10961 0x15dea448c536070a,
10962 >(_buf?)?
10963 .into_result::<BufferCollectionTokenGroupMarker>("create_children_sync")?;
10964 Ok(_response)
10965 }
10966 self.client.send_query_and_decode::<
10967 BufferCollectionTokenGroupCreateChildrenSyncRequest,
10968 BufferCollectionTokenGroupCreateChildrenSyncResponse,
10969 >(
10970 payload,
10971 0x15dea448c536070a,
10972 fidl::encoding::DynamicFlags::FLEXIBLE,
10973 _decode,
10974 )
10975 }
10976
10977 fn r#all_children_present(&self) -> Result<(), fidl::Error> {
10978 self.client.send::<fidl::encoding::EmptyPayload>(
10979 (),
10980 0x5c327e4a23391312,
10981 fidl::encoding::DynamicFlags::FLEXIBLE,
10982 )
10983 }
10984}
10985
10986pub struct BufferCollectionTokenGroupEventStream {
10987 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
10988}
10989
10990impl std::marker::Unpin for BufferCollectionTokenGroupEventStream {}
10991
10992impl futures::stream::FusedStream for BufferCollectionTokenGroupEventStream {
10993 fn is_terminated(&self) -> bool {
10994 self.event_receiver.is_terminated()
10995 }
10996}
10997
10998impl futures::Stream for BufferCollectionTokenGroupEventStream {
10999 type Item = Result<BufferCollectionTokenGroupEvent, fidl::Error>;
11000
11001 fn poll_next(
11002 mut self: std::pin::Pin<&mut Self>,
11003 cx: &mut std::task::Context<'_>,
11004 ) -> std::task::Poll<Option<Self::Item>> {
11005 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
11006 &mut self.event_receiver,
11007 cx
11008 )?) {
11009 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenGroupEvent::decode(buf))),
11010 None => std::task::Poll::Ready(None),
11011 }
11012 }
11013}
11014
11015#[derive(Debug)]
11016pub enum BufferCollectionTokenGroupEvent {
11017 #[non_exhaustive]
11018 _UnknownEvent {
11019 /// Ordinal of the event that was sent.
11020 ordinal: u64,
11021 },
11022}
11023
11024impl BufferCollectionTokenGroupEvent {
11025 /// Decodes a message buffer as a [`BufferCollectionTokenGroupEvent`].
11026 fn decode(
11027 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
11028 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
11029 let (bytes, _handles) = buf.split_mut();
11030 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
11031 debug_assert_eq!(tx_header.tx_id, 0);
11032 match tx_header.ordinal {
11033 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
11034 Ok(BufferCollectionTokenGroupEvent::_UnknownEvent {
11035 ordinal: tx_header.ordinal,
11036 })
11037 }
11038 _ => Err(fidl::Error::UnknownOrdinal {
11039 ordinal: tx_header.ordinal,
11040 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
11041 })
11042 }
11043 }
11044}
11045
11046/// A Stream of incoming requests for fuchsia.sysmem2/BufferCollectionTokenGroup.
11047pub struct BufferCollectionTokenGroupRequestStream {
11048 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11049 is_terminated: bool,
11050}
11051
11052impl std::marker::Unpin for BufferCollectionTokenGroupRequestStream {}
11053
11054impl futures::stream::FusedStream for BufferCollectionTokenGroupRequestStream {
11055 fn is_terminated(&self) -> bool {
11056 self.is_terminated
11057 }
11058}
11059
11060impl fidl::endpoints::RequestStream for BufferCollectionTokenGroupRequestStream {
11061 type Protocol = BufferCollectionTokenGroupMarker;
11062 type ControlHandle = BufferCollectionTokenGroupControlHandle;
11063
11064 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
11065 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
11066 }
11067
11068 fn control_handle(&self) -> Self::ControlHandle {
11069 BufferCollectionTokenGroupControlHandle { inner: self.inner.clone() }
11070 }
11071
11072 fn into_inner(
11073 self,
11074 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
11075 {
11076 (self.inner, self.is_terminated)
11077 }
11078
11079 fn from_inner(
11080 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11081 is_terminated: bool,
11082 ) -> Self {
11083 Self { inner, is_terminated }
11084 }
11085}
11086
11087impl futures::Stream for BufferCollectionTokenGroupRequestStream {
11088 type Item = Result<BufferCollectionTokenGroupRequest, fidl::Error>;
11089
11090 fn poll_next(
11091 mut self: std::pin::Pin<&mut Self>,
11092 cx: &mut std::task::Context<'_>,
11093 ) -> std::task::Poll<Option<Self::Item>> {
11094 let this = &mut *self;
11095 if this.inner.check_shutdown(cx) {
11096 this.is_terminated = true;
11097 return std::task::Poll::Ready(None);
11098 }
11099 if this.is_terminated {
11100 panic!("polled BufferCollectionTokenGroupRequestStream after completion");
11101 }
11102 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
11103 |bytes, handles| {
11104 match this.inner.channel().read_etc(cx, bytes, handles) {
11105 std::task::Poll::Ready(Ok(())) => {}
11106 std::task::Poll::Pending => return std::task::Poll::Pending,
11107 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
11108 this.is_terminated = true;
11109 return std::task::Poll::Ready(None);
11110 }
11111 std::task::Poll::Ready(Err(e)) => {
11112 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
11113 e.into(),
11114 ))));
11115 }
11116 }
11117
11118 // A message has been received from the channel
11119 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
11120
11121 std::task::Poll::Ready(Some(match header.ordinal {
11122 0x11ac2555cf575b54 => {
11123 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11124 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11125 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11126 let control_handle = BufferCollectionTokenGroupControlHandle {
11127 inner: this.inner.clone(),
11128 };
11129 Ok(BufferCollectionTokenGroupRequest::Sync {
11130 responder: BufferCollectionTokenGroupSyncResponder {
11131 control_handle: std::mem::ManuallyDrop::new(control_handle),
11132 tx_id: header.tx_id,
11133 },
11134 })
11135 }
11136 0x6a5cae7d6d6e04c6 => {
11137 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11138 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11139 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11140 let control_handle = BufferCollectionTokenGroupControlHandle {
11141 inner: this.inner.clone(),
11142 };
11143 Ok(BufferCollectionTokenGroupRequest::Release {
11144 control_handle,
11145 })
11146 }
11147 0xb41f1624f48c1e9 => {
11148 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11149 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11150 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
11151 let control_handle = BufferCollectionTokenGroupControlHandle {
11152 inner: this.inner.clone(),
11153 };
11154 Ok(BufferCollectionTokenGroupRequest::SetName {payload: req,
11155 control_handle,
11156 })
11157 }
11158 0x5cde8914608d99b1 => {
11159 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11160 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11161 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
11162 let control_handle = BufferCollectionTokenGroupControlHandle {
11163 inner: this.inner.clone(),
11164 };
11165 Ok(BufferCollectionTokenGroupRequest::SetDebugClientInfo {payload: req,
11166 control_handle,
11167 })
11168 }
11169 0x716b0af13d5c0806 => {
11170 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11171 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11172 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
11173 let control_handle = BufferCollectionTokenGroupControlHandle {
11174 inner: this.inner.clone(),
11175 };
11176 Ok(BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {payload: req,
11177 control_handle,
11178 })
11179 }
11180 0x5209c77415b4dfad => {
11181 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11182 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11183 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11184 let control_handle = BufferCollectionTokenGroupControlHandle {
11185 inner: this.inner.clone(),
11186 };
11187 Ok(BufferCollectionTokenGroupRequest::SetVerboseLogging {
11188 control_handle,
11189 })
11190 }
11191 0x5b3d0e51614df053 => {
11192 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11193 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11194 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11195 let control_handle = BufferCollectionTokenGroupControlHandle {
11196 inner: this.inner.clone(),
11197 };
11198 Ok(BufferCollectionTokenGroupRequest::GetNodeRef {
11199 responder: BufferCollectionTokenGroupGetNodeRefResponder {
11200 control_handle: std::mem::ManuallyDrop::new(control_handle),
11201 tx_id: header.tx_id,
11202 },
11203 })
11204 }
11205 0x3a58e00157e0825 => {
11206 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11207 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11208 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
11209 let control_handle = BufferCollectionTokenGroupControlHandle {
11210 inner: this.inner.clone(),
11211 };
11212 Ok(BufferCollectionTokenGroupRequest::IsAlternateFor {payload: req,
11213 responder: BufferCollectionTokenGroupIsAlternateForResponder {
11214 control_handle: std::mem::ManuallyDrop::new(control_handle),
11215 tx_id: header.tx_id,
11216 },
11217 })
11218 }
11219 0x77d19a494b78ba8c => {
11220 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11221 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11222 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11223 let control_handle = BufferCollectionTokenGroupControlHandle {
11224 inner: this.inner.clone(),
11225 };
11226 Ok(BufferCollectionTokenGroupRequest::GetBufferCollectionId {
11227 responder: BufferCollectionTokenGroupGetBufferCollectionIdResponder {
11228 control_handle: std::mem::ManuallyDrop::new(control_handle),
11229 tx_id: header.tx_id,
11230 },
11231 })
11232 }
11233 0x22dd3ea514eeffe1 => {
11234 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11235 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11236 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11237 let control_handle = BufferCollectionTokenGroupControlHandle {
11238 inner: this.inner.clone(),
11239 };
11240 Ok(BufferCollectionTokenGroupRequest::SetWeak {
11241 control_handle,
11242 })
11243 }
11244 0x38a44fc4d7724be9 => {
11245 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11246 let mut req = fidl::new_empty!(NodeSetWeakOkRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11247 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetWeakOkRequest>(&header, _body_bytes, handles, &mut req)?;
11248 let control_handle = BufferCollectionTokenGroupControlHandle {
11249 inner: this.inner.clone(),
11250 };
11251 Ok(BufferCollectionTokenGroupRequest::SetWeakOk {payload: req,
11252 control_handle,
11253 })
11254 }
11255 0x3f22f2a293d3cdac => {
11256 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11257 let mut req = fidl::new_empty!(NodeAttachNodeTrackingRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11258 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeAttachNodeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
11259 let control_handle = BufferCollectionTokenGroupControlHandle {
11260 inner: this.inner.clone(),
11261 };
11262 Ok(BufferCollectionTokenGroupRequest::AttachNodeTracking {payload: req,
11263 control_handle,
11264 })
11265 }
11266 0x41a0075d419f30c5 => {
11267 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11268 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11269 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildRequest>(&header, _body_bytes, handles, &mut req)?;
11270 let control_handle = BufferCollectionTokenGroupControlHandle {
11271 inner: this.inner.clone(),
11272 };
11273 Ok(BufferCollectionTokenGroupRequest::CreateChild {payload: req,
11274 control_handle,
11275 })
11276 }
11277 0x15dea448c536070a => {
11278 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11279 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildrenSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
11280 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildrenSyncRequest>(&header, _body_bytes, handles, &mut req)?;
11281 let control_handle = BufferCollectionTokenGroupControlHandle {
11282 inner: this.inner.clone(),
11283 };
11284 Ok(BufferCollectionTokenGroupRequest::CreateChildrenSync {payload: req,
11285 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder {
11286 control_handle: std::mem::ManuallyDrop::new(control_handle),
11287 tx_id: header.tx_id,
11288 },
11289 })
11290 }
11291 0x5c327e4a23391312 => {
11292 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
11293 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
11294 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11295 let control_handle = BufferCollectionTokenGroupControlHandle {
11296 inner: this.inner.clone(),
11297 };
11298 Ok(BufferCollectionTokenGroupRequest::AllChildrenPresent {
11299 control_handle,
11300 })
11301 }
11302 _ if header.tx_id == 0 && header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
11303 Ok(BufferCollectionTokenGroupRequest::_UnknownMethod {
11304 ordinal: header.ordinal,
11305 control_handle: BufferCollectionTokenGroupControlHandle { inner: this.inner.clone() },
11306 method_type: fidl::MethodType::OneWay,
11307 })
11308 }
11309 _ if header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
11310 this.inner.send_framework_err(
11311 fidl::encoding::FrameworkErr::UnknownMethod,
11312 header.tx_id,
11313 header.ordinal,
11314 header.dynamic_flags(),
11315 (bytes, handles),
11316 )?;
11317 Ok(BufferCollectionTokenGroupRequest::_UnknownMethod {
11318 ordinal: header.ordinal,
11319 control_handle: BufferCollectionTokenGroupControlHandle { inner: this.inner.clone() },
11320 method_type: fidl::MethodType::TwoWay,
11321 })
11322 }
11323 _ => Err(fidl::Error::UnknownOrdinal {
11324 ordinal: header.ordinal,
11325 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
11326 }),
11327 }))
11328 },
11329 )
11330 }
11331}
11332
11333/// The sysmem implementation is consistent with a logical / conceptual model of
11334/// allocation / logical allocation as follows:
11335///
11336/// As usual, a logical allocation considers either the root and all nodes with
11337/// connectivity to the root that don't transit a [`fuchsia.sysmem2/Node`]
11338/// created with [`fuchsia.sysmem2/BufferCollection.AttachToken`], or a subtree
11339/// rooted at an `AttachToken` `Node` and all `Node`(s) with connectivity to
11340/// that subtree that don't transit another `AttachToken`. This is called the
11341/// logical allocation pruned subtree, or pruned subtree for short.
11342///
11343/// During constraints aggregation, each
11344/// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] will select a single child
11345/// `Node` among its direct children. The rest of the children will appear to
11346/// fail the logical allocation, while the selected child may succeed.
11347///
11348/// When more than one `BufferCollectionTokenGroup` exists in the overall
11349/// logical allocation pruned subtree, the relative priority between two groups
11350/// is equivalent to their ordering in a DFS pre-order iteration of the tree,
11351/// with parents higher priority than children, and left children higher
11352/// priority than right children.
11353///
11354/// When a particular child of a group is selected (whether provisionally during
11355/// a constraints aggregation attempt, or as a final selection), the
11356/// non-selection of other children of the group will "hide" any other groups
11357/// under those non-selected children.
11358///
11359/// Within a logical allocation, aggregation is attempted first by provisionally
11360/// selecting child 0 of the highest-priority group, and child 0 of the next
11361/// highest-priority group that isn't hidden by the provisional selections so
11362/// far, etc.
11363///
11364/// If that aggregation attempt fails, aggregation will be attempted with the
11365/// ordinal 0 child of all the same groups except the lowest priority non-hidden
11366/// group which will provisionally select its ordinal 1 child (and then child 2
11367/// and so on). If a new lowest-priority group is un-hidden as provisional
11368/// selections are updated, that newly un-hidden lowest-priority group has all
11369/// its children considered in order, before changing the provisional selection
11370/// in the former lowest-priority group. In terms of result, this is equivalent
11371/// to systematic enumeration of all possible combinations of choices in a
11372/// counting-like order updating the lowest-priority group the most often and
11373/// the highest-priority group the least often. Rather than actually attempting
11374/// aggregation with all the combinations, we can skip over combinations which
11375/// are redundant/equivalent due to hiding without any change to the result.
11376///
11377/// Attempted constraint aggregations of enumerated non-equivalent combinations
11378/// of choices continue in this manner until either (a) all aggregation attempts
11379/// fail in which case the overall logical allocation fails, or (b) until an
11380/// attempted aggregation succeeds, in which case buffer allocation (if needed;
11381/// if this is the pruned subtree rooted at the overall root `Node`) is
11382/// attempted once. If buffer allocation based on the first successful
11383/// constraints aggregation fails, the overall logical allocation fails (there
11384/// is no buffer allocation retry / re-attempt). If buffer allocation succeeds
11385/// (or is not needed due to being a pruned subtree that doesn't include the
11386/// root), the logical allocation succeeds.
11387///
11388/// If this prioritization scheme cannot reasonably work for your usage of
11389/// sysmem, please don't hesitate to contact sysmem folks to discuss potentially
11390/// adding a way to achieve what you need.
11391///
11392/// Please avoid creating a large number of `BufferCollectionTokenGroup`(s) per
11393/// logical allocation, especially with large number of children overall, and
11394/// especially in cases where aggregation may reasonably be expected to often
11395/// fail using ordinal 0 children and possibly with later children as well.
11396/// Sysmem mitigates potentially high time complexity of evaluating too many
11397/// child combinations/selections across too many groups by simply failing
11398/// logical allocation beyond a certain (fairly high, but not huge) max number
11399/// of considered group child combinations/selections. More advanced (and more
11400/// complicated) mitigation is not anticipated to be practically necessary or
11401/// worth the added complexity. Please contact sysmem folks if the max limit is
11402/// getting hit or if you anticipate it getting hit, to discuss potential
11403/// options.
11404///
11405/// Prefer to use multiple [`fuchsia.sysmem2/ImageFormatConstraints`] in a
11406/// single [`fuchsia.sysmem2/BufferCollectionConstraints`] when feasible (when a
11407/// participant just needs to express the ability to work with more than a
11408/// single [`fuchsia.images2/PixelFormat`], with sysmem choosing which
11409/// `PixelFormat` to use among those supported by all participants).
11410///
11411/// Similar to [`fuchsia.sysmem2/BufferCollectionToken`] and
11412/// [`fuchsia.sysmem2/BufferCollection`], closure of the
11413/// `BufferCollectionTokenGroup` channel without sending
11414/// [`fuchsia.sysmem2/Node.Release`] first will cause buffer collection failure
11415/// (or subtree failure if using
11416/// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
11417/// [`fuchsia.sysmem2/BufferCollection.AttachToken`] and the
11418/// `BufferCollectionTokenGroup` is part of a subtree under such a node that
11419/// doesn't propagate failure to its parent).
11420///
11421/// Epitaphs are not used in this protocol.
11422#[derive(Debug)]
11423pub enum BufferCollectionTokenGroupRequest {
11424 /// Ensure that previous messages have been received server side. This is
11425 /// particularly useful after previous messages that created new tokens,
11426 /// because a token must be known to the sysmem server before sending the
11427 /// token to another participant.
11428 ///
11429 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
11430 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
11431 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
11432 /// to mitigate the possibility of a hostile/fake
11433 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
11434 /// Another way is to pass the token to
11435 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
11436 /// the token as part of exchanging it for a
11437 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
11438 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
11439 /// of stalling.
11440 ///
11441 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
11442 /// and then starting and completing a `Sync`, it's then safe to send the
11443 /// `BufferCollectionToken` client ends to other participants knowing the
11444 /// server will recognize the tokens when they're sent by the other
11445 /// participants to sysmem in a
11446 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
11447 /// efficient way to create tokens while avoiding unnecessary round trips.
11448 ///
11449 /// Other options include waiting for each
11450 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
11451 /// individually (using separate call to `Sync` after each), or calling
11452 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
11453 /// converted to a `BufferCollection` via
11454 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
11455 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
11456 /// the sync step and can create multiple tokens at once.
11457 Sync { responder: BufferCollectionTokenGroupSyncResponder },
11458 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
11459 ///
11460 /// Normally a participant will convert a `BufferCollectionToken` into a
11461 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
11462 /// `Release` via the token (and then close the channel immediately or
11463 /// shortly later in response to server closing the server end), which
11464 /// avoids causing buffer collection failure. Without a prior `Release`,
11465 /// closing the `BufferCollectionToken` client end will cause buffer
11466 /// collection failure.
11467 ///
11468 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
11469 ///
11470 /// By default the server handles unexpected closure of a
11471 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
11472 /// first) by failing the buffer collection. Partly this is to expedite
11473 /// closing VMO handles to reclaim memory when any participant fails. If a
11474 /// participant would like to cleanly close a `BufferCollection` without
11475 /// causing buffer collection failure, the participant can send `Release`
11476 /// before closing the `BufferCollection` client end. The `Release` can
11477 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
11478 /// buffer collection won't require constraints from this node in order to
11479 /// allocate. If after `SetConstraints`, the constraints are retained and
11480 /// aggregated, despite the lack of `BufferCollection` connection at the
11481 /// time of constraints aggregation.
11482 ///
11483 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
11484 ///
11485 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
11486 /// end (without `Release` first) will trigger failure of the buffer
11487 /// collection. To close a `BufferCollectionTokenGroup` channel without
11488 /// failing the buffer collection, ensure that AllChildrenPresent() has been
11489 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
11490 /// client end.
11491 ///
11492 /// If `Release` occurs before
11493 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
11494 /// buffer collection will fail (triggered by reception of `Release` without
11495 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
11496 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
11497 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
11498 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
11499 /// close requires `AllChildrenPresent` (if not already sent), then
11500 /// `Release`, then close client end.
11501 ///
11502 /// If `Release` occurs after `AllChildrenPresent`, the children and all
11503 /// their constraints remain intact (just as they would if the
11504 /// `BufferCollectionTokenGroup` channel had remained open), and the client
11505 /// end close doesn't trigger buffer collection failure.
11506 ///
11507 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
11508 ///
11509 /// For brevity, the per-channel-protocol paragraphs above ignore the
11510 /// separate failure domain created by
11511 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
11512 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
11513 /// unexpectedly closes (without `Release` first) and that client end is
11514 /// under a failure domain, instead of failing the whole buffer collection,
11515 /// the failure domain is failed, but the buffer collection itself is
11516 /// isolated from failure of the failure domain. Such failure domains can be
11517 /// nested, in which case only the inner-most failure domain in which the
11518 /// `Node` resides fails.
11519 Release { control_handle: BufferCollectionTokenGroupControlHandle },
11520 /// Set a name for VMOs in this buffer collection.
11521 ///
11522 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
11523 /// will be truncated to fit. The name of the vmo will be suffixed with the
11524 /// buffer index within the collection (if the suffix fits within
11525 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
11526 /// listed in the inspect data.
11527 ///
11528 /// The name only affects VMOs allocated after the name is set; this call
11529 /// does not rename existing VMOs. If multiple clients set different names
11530 /// then the larger priority value will win. Setting a new name with the
11531 /// same priority as a prior name doesn't change the name.
11532 ///
11533 /// All table fields are currently required.
11534 ///
11535 /// + request `priority` The name is only set if this is the first `SetName`
11536 /// or if `priority` is greater than any previous `priority` value in
11537 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
11538 /// + request `name` The name for VMOs created under this buffer collection.
11539 SetName { payload: NodeSetNameRequest, control_handle: BufferCollectionTokenGroupControlHandle },
11540 /// Set information about the current client that can be used by sysmem to
11541 /// help diagnose leaking memory and allocation stalls waiting for a
11542 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
11543 ///
11544 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
11545 /// `Node`(s) derived from this `Node`, unless overriden by
11546 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
11547 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
11548 ///
11549 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
11550 /// `Allocator` is the most efficient way to ensure that all
11551 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
11552 /// set, and is also more efficient than separately sending the same debug
11553 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
11554 /// created [`fuchsia.sysmem2/Node`].
11555 ///
11556 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
11557 /// indicate which client is closing their channel first, leading to subtree
11558 /// failure (which can be normal if the purpose of the subtree is over, but
11559 /// if happening earlier than expected, the client-channel-specific name can
11560 /// help diagnose where the failure is first coming from, from sysmem's
11561 /// point of view).
11562 ///
11563 /// All table fields are currently required.
11564 ///
11565 /// + request `name` This can be an arbitrary string, but the current
11566 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
11567 /// + request `id` This can be an arbitrary id, but the current process ID
11568 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
11569 SetDebugClientInfo {
11570 payload: NodeSetDebugClientInfoRequest,
11571 control_handle: BufferCollectionTokenGroupControlHandle,
11572 },
11573 /// Sysmem logs a warning if sysmem hasn't seen
11574 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
11575 /// within 5 seconds after creation of a new collection.
11576 ///
11577 /// Clients can call this method to change when the log is printed. If
11578 /// multiple client set the deadline, it's unspecified which deadline will
11579 /// take effect.
11580 ///
11581 /// In most cases the default works well.
11582 ///
11583 /// All table fields are currently required.
11584 ///
11585 /// + request `deadline` The time at which sysmem will start trying to log
11586 /// the warning, unless all constraints are with sysmem by then.
11587 SetDebugTimeoutLogDeadline {
11588 payload: NodeSetDebugTimeoutLogDeadlineRequest,
11589 control_handle: BufferCollectionTokenGroupControlHandle,
11590 },
11591 /// This enables verbose logging for the buffer collection.
11592 ///
11593 /// Verbose logging includes constraints set via
11594 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
11595 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
11596 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
11597 /// the tree of `Node`(s).
11598 ///
11599 /// Normally sysmem prints only a single line complaint when aggregation
11600 /// fails, with just the specific detailed reason that aggregation failed,
11601 /// with little surrounding context. While this is often enough to diagnose
11602 /// a problem if only a small change was made and everything was working
11603 /// before the small change, it's often not particularly helpful for getting
11604 /// a new buffer collection to work for the first time. Especially with
11605 /// more complex trees of nodes, involving things like
11606 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
11607 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
11608 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
11609 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
11610 /// looks like and why it's failing a logical allocation, or why a tree or
11611 /// subtree is failing sooner than expected.
11612 ///
11613 /// The intent of the extra logging is to be acceptable from a performance
11614 /// point of view, under the assumption that verbose logging is only enabled
11615 /// on a low number of buffer collections. If we're not tracking down a bug,
11616 /// we shouldn't send this message.
11617 SetVerboseLogging { control_handle: BufferCollectionTokenGroupControlHandle },
11618 /// This gets a handle that can be used as a parameter to
11619 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
11620 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
11621 /// client obtained this handle from this `Node`.
11622 ///
11623 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
11624 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
11625 /// despite the two calls typically being on different channels.
11626 ///
11627 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
11628 ///
11629 /// All table fields are currently required.
11630 ///
11631 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
11632 /// different `Node` channel, to prove that the client obtained the handle
11633 /// from this `Node`.
11634 GetNodeRef { responder: BufferCollectionTokenGroupGetNodeRefResponder },
11635 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
11636 /// rooted at a different child token of a common parent
11637 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
11638 /// passed-in `node_ref`.
11639 ///
11640 /// This call is for assisting with admission control de-duplication, and
11641 /// with debugging.
11642 ///
11643 /// The `node_ref` must be obtained using
11644 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
11645 ///
11646 /// The `node_ref` can be a duplicated handle; it's not necessary to call
11647 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
11648 ///
11649 /// If a calling token may not actually be a valid token at all due to a
11650 /// potentially hostile/untrusted provider of the token, call
11651 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
11652 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
11653 /// never responds due to a calling token not being a real token (not really
11654 /// talking to sysmem). Another option is to call
11655 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
11656 /// which also validates the token along with converting it to a
11657 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
11658 ///
11659 /// All table fields are currently required.
11660 ///
11661 /// - response `is_alternate`
11662 /// - true: The first parent node in common between the calling node and
11663 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
11664 /// that the calling `Node` and the `node_ref` `Node` will not have both
11665 /// their constraints apply - rather sysmem will choose one or the other
11666 /// of the constraints - never both. This is because only one child of
11667 /// a `BufferCollectionTokenGroup` is selected during logical
11668 /// allocation, with only that one child's subtree contributing to
11669 /// constraints aggregation.
11670 /// - false: The first parent node in common between the calling `Node`
11671 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
11672 /// Currently, this means the first parent node in common is a
11673 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
11674 /// `Release`ed). This means that the calling `Node` and the `node_ref`
11675 /// `Node` may have both their constraints apply during constraints
11676 /// aggregation of the logical allocation, if both `Node`(s) are
11677 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
11678 /// this case, there is no `BufferCollectionTokenGroup` that will
11679 /// directly prevent the two `Node`(s) from both being selected and
11680 /// their constraints both aggregated, but even when false, one or both
11681 /// `Node`(s) may still be eliminated from consideration if one or both
11682 /// `Node`(s) has a direct or indirect parent
11683 /// `BufferCollectionTokenGroup` which selects a child subtree other
11684 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
11685 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
11686 /// associated with the same buffer collection as the calling `Node`.
11687 /// Another reason for this error is if the `node_ref` is an
11688 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
11689 /// a real `node_ref` obtained from `GetNodeRef`.
11690 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
11691 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
11692 /// the needed rights expected on a real `node_ref`.
11693 /// * No other failing status codes are returned by this call. However,
11694 /// sysmem may add additional codes in future, so the client should have
11695 /// sensible default handling for any failing status code.
11696 IsAlternateFor {
11697 payload: NodeIsAlternateForRequest,
11698 responder: BufferCollectionTokenGroupIsAlternateForResponder,
11699 },
11700 /// Get the buffer collection ID. This ID is also available from
11701 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
11702 /// within the collection).
11703 ///
11704 /// This call is mainly useful in situations where we can't convey a
11705 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
11706 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
11707 /// handle, which can be joined back up with a `BufferCollection` client end
11708 /// that was created via a different path. Prefer to convey a
11709 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
11710 ///
11711 /// Trusting a `buffer_collection_id` value from a source other than sysmem
11712 /// is analogous to trusting a koid value from a source other than zircon.
11713 /// Both should be avoided unless really necessary, and both require
11714 /// caution. In some situations it may be reasonable to refer to a
11715 /// pre-established `BufferCollection` by `buffer_collection_id` via a
11716 /// protocol for efficiency reasons, but an incoming value purporting to be
11717 /// a `buffer_collection_id` is not sufficient alone to justify granting the
11718 /// sender of the `buffer_collection_id` any capability. The sender must
11719 /// first prove to a receiver that the sender has/had a VMO or has/had a
11720 /// `BufferCollectionToken` to the same collection by sending a handle that
11721 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
11722 /// `buffer_collection_id` value. The receiver should take care to avoid
11723 /// assuming that a sender had a `BufferCollectionToken` in cases where the
11724 /// sender has only proven that the sender had a VMO.
11725 ///
11726 /// - response `buffer_collection_id` This ID is unique per buffer
11727 /// collection per boot. Each buffer is uniquely identified by the
11728 /// `buffer_collection_id` and `buffer_index` together.
11729 GetBufferCollectionId { responder: BufferCollectionTokenGroupGetBufferCollectionIdResponder },
11730 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
11731 /// created after this message to weak, which means that a client's `Node`
11732 /// client end (or a child created after this message) is not alone
11733 /// sufficient to keep allocated VMOs alive.
11734 ///
11735 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
11736 /// `close_weak_asap`.
11737 ///
11738 /// This message is only permitted before the `Node` becomes ready for
11739 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
11740 /// * `BufferCollectionToken`: any time
11741 /// * `BufferCollection`: before `SetConstraints`
11742 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
11743 ///
11744 /// Currently, no conversion from strong `Node` to weak `Node` after ready
11745 /// for allocation is provided, but a client can simulate that by creating
11746 /// an additional `Node` before allocation and setting that additional
11747 /// `Node` to weak, and then potentially at some point later sending
11748 /// `Release` and closing the client end of the client's strong `Node`, but
11749 /// keeping the client's weak `Node`.
11750 ///
11751 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
11752 /// collection failure (all `Node` client end(s) will see
11753 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
11754 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
11755 /// this situation until all `Node`(s) are ready for allocation. For initial
11756 /// allocation to succeed, at least one strong `Node` is required to exist
11757 /// at allocation time, but after that client receives VMO handles, that
11758 /// client can `BufferCollection.Release` and close the client end without
11759 /// causing this type of failure.
11760 ///
11761 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
11762 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
11763 /// separately as appropriate.
11764 SetWeak { control_handle: BufferCollectionTokenGroupControlHandle },
11765 /// This indicates to sysmem that the client is prepared to pay attention to
11766 /// `close_weak_asap`.
11767 ///
11768 /// If sent, this message must be before
11769 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
11770 ///
11771 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
11772 /// send this message before `WaitForAllBuffersAllocated`, or a parent
11773 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
11774 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
11775 /// trigger buffer collection failure.
11776 ///
11777 /// This message is necessary because weak sysmem VMOs have not always been
11778 /// a thing, so older clients are not aware of the need to pay attention to
11779 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
11780 /// sysmem weak VMO handles asap. By having this message and requiring
11781 /// participants to indicate their acceptance of this aspect of the overall
11782 /// protocol, we avoid situations where an older client is delivered a weak
11783 /// VMO without any way for sysmem to get that VMO to close quickly later
11784 /// (and on a per-buffer basis).
11785 ///
11786 /// A participant that doesn't handle `close_weak_asap` and also doesn't
11787 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
11788 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
11789 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
11790 /// same participant has a child/delegate which does retrieve VMOs, that
11791 /// child/delegate will need to send `SetWeakOk` before
11792 /// `WaitForAllBuffersAllocated`.
11793 ///
11794 /// + request `for_child_nodes_also` If present and true, this means direct
11795 /// child nodes of this node created after this message plus all
11796 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
11797 /// those nodes. Any child node of this node that was created before this
11798 /// message is not included. This setting is "sticky" in the sense that a
11799 /// subsequent `SetWeakOk` without this bool set to true does not reset
11800 /// the server-side bool. If this creates a problem for a participant, a
11801 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
11802 /// tokens instead, as appropriate. A participant should only set
11803 /// `for_child_nodes_also` true if the participant can really promise to
11804 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
11805 /// weak VMO handles held by participants holding the corresponding child
11806 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
11807 /// which are using sysmem(1) can be weak, despite the clients of those
11808 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
11809 /// direct way to find out about `close_weak_asap`. This only applies to
11810 /// descendents of this `Node` which are using sysmem(1), not to this
11811 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
11812 /// token, which will fail allocation unless an ancestor of this `Node`
11813 /// specified `for_child_nodes_also` true.
11814 SetWeakOk {
11815 payload: NodeSetWeakOkRequest,
11816 control_handle: BufferCollectionTokenGroupControlHandle,
11817 },
11818 /// The server_end will be closed after this `Node` and any child nodes have
11819 /// have released their buffer counts, making those counts available for
11820 /// reservation by a different `Node` via
11821 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
11822 ///
11823 /// The `Node` buffer counts may not be released until the entire tree of
11824 /// `Node`(s) is closed or failed, because
11825 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
11826 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
11827 /// `Node` buffer counts remain reserved until the orphaned node is later
11828 /// cleaned up.
11829 ///
11830 /// If the `Node` exceeds a fairly large number of attached eventpair server
11831 /// ends, a log message will indicate this and the `Node` (and the
11832 /// appropriate) sub-tree will fail.
11833 ///
11834 /// The `server_end` will remain open when
11835 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
11836 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
11837 /// [`fuchsia.sysmem2/BufferCollection`].
11838 ///
11839 /// This message can also be used with a
11840 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
11841 AttachNodeTracking {
11842 payload: NodeAttachNodeTrackingRequest,
11843 control_handle: BufferCollectionTokenGroupControlHandle,
11844 },
11845 /// Create a child [`fuchsia.sysmem2/BufferCollectionToken`]. Only one child
11846 /// (including its children) will be selected during allocation (or logical
11847 /// allocation).
11848 ///
11849 /// Before passing the client end of this token to
11850 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], completion of
11851 /// [`fuchsia.sysmem2/Node.Sync`] after
11852 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] is required.
11853 /// Or the client can use
11854 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`] which
11855 /// essentially includes the `Sync`.
11856 ///
11857 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
11858 /// fail the group's subtree and close the connection.
11859 ///
11860 /// After all children have been created, send AllChildrenPresent.
11861 ///
11862 /// + request `token_request` The server end of the new token channel.
11863 /// + request `rights_attenuation_mask` If ZX_RIGHT_SAME_RIGHTS, the created
11864 /// token allows the holder to get the same rights to buffers as the
11865 /// parent token (of the group) had. When the value isn't
11866 /// ZX_RIGHT_SAME_RIGHTS, the value is interpretted as a bitmask with 0
11867 /// bits ensuring those rights are attentuated, so 0xFFFFFFFF is a synonym
11868 /// for ZX_RIGHT_SAME_RIGHTS. The value 0 is not allowed and intentionally
11869 /// causes subtree failure.
11870 CreateChild {
11871 payload: BufferCollectionTokenGroupCreateChildRequest,
11872 control_handle: BufferCollectionTokenGroupControlHandle,
11873 },
11874 /// Create 1 or more child tokens at once, synchronously. In contrast to
11875 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`], no
11876 /// [`fuchsia.sysmem2/Node.Sync`] is required before passing the client end
11877 /// of a returned token to
11878 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`].
11879 ///
11880 /// The lower-index child tokens are higher priority (attempted sooner) than
11881 /// higher-index child tokens.
11882 ///
11883 /// As per all child tokens, successful aggregation will choose exactly one
11884 /// child among all created children (across all children created across
11885 /// potentially multiple calls to
11886 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild`] and
11887 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync`]).
11888 ///
11889 /// The maximum permissible total number of children per group, and total
11890 /// number of nodes in an overall tree (from the root) are capped to limits
11891 /// which are not configurable via these protocols.
11892 ///
11893 /// Sending CreateChildrenSync after AllChildrenPresent is not permitted;
11894 /// this will fail the group's subtree and close the connection.
11895 ///
11896 /// After all children have been created, send AllChildrenPresent.
11897 ///
11898 /// + request `rights_attentuation_masks` The size of the
11899 /// `rights_attentuation_masks` determines the number of created child
11900 /// tokens. The value ZX_RIGHT_SAME_RIGHTS doesn't attenuate any rights.
11901 /// The value 0xFFFFFFFF is a synonym for ZX_RIGHT_SAME_RIGHTS. For any
11902 /// other value, each 0 bit in the mask attenuates that right.
11903 /// - response `tokens` The created child tokens.
11904 CreateChildrenSync {
11905 payload: BufferCollectionTokenGroupCreateChildrenSyncRequest,
11906 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder,
11907 },
11908 /// Indicate that no more children will be created.
11909 ///
11910 /// After creating all children, the client should send
11911 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent`] to
11912 /// inform sysmem that no more children will be created, so that sysmem can
11913 /// know when it's ok to start aggregating constraints.
11914 ///
11915 /// Sending CreateChild after AllChildrenPresent is not permitted; this will
11916 /// fail the group's subtree and close the connection.
11917 ///
11918 /// If [`fuchsia.sysmem2/Node.Release`] is to be sent, it should be sent
11919 /// after `AllChildrenPresent`, else failure of the group's subtree will be
11920 /// triggered. This is intentionally not analogous to how `Release` without
11921 /// prior [`fuchsia.sysmem2/BufferCollection.SetConstraints`] doesn't cause
11922 /// subtree failure.
11923 AllChildrenPresent { control_handle: BufferCollectionTokenGroupControlHandle },
11924 /// An interaction was received which does not match any known method.
11925 #[non_exhaustive]
11926 _UnknownMethod {
11927 /// Ordinal of the method that was called.
11928 ordinal: u64,
11929 control_handle: BufferCollectionTokenGroupControlHandle,
11930 method_type: fidl::MethodType,
11931 },
11932}
11933
11934impl BufferCollectionTokenGroupRequest {
11935 #[allow(irrefutable_let_patterns)]
11936 pub fn into_sync(self) -> Option<(BufferCollectionTokenGroupSyncResponder)> {
11937 if let BufferCollectionTokenGroupRequest::Sync { responder } = self {
11938 Some((responder))
11939 } else {
11940 None
11941 }
11942 }
11943
11944 #[allow(irrefutable_let_patterns)]
11945 pub fn into_release(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
11946 if let BufferCollectionTokenGroupRequest::Release { control_handle } = self {
11947 Some((control_handle))
11948 } else {
11949 None
11950 }
11951 }
11952
11953 #[allow(irrefutable_let_patterns)]
11954 pub fn into_set_name(
11955 self,
11956 ) -> Option<(NodeSetNameRequest, BufferCollectionTokenGroupControlHandle)> {
11957 if let BufferCollectionTokenGroupRequest::SetName { payload, control_handle } = self {
11958 Some((payload, control_handle))
11959 } else {
11960 None
11961 }
11962 }
11963
11964 #[allow(irrefutable_let_patterns)]
11965 pub fn into_set_debug_client_info(
11966 self,
11967 ) -> Option<(NodeSetDebugClientInfoRequest, BufferCollectionTokenGroupControlHandle)> {
11968 if let BufferCollectionTokenGroupRequest::SetDebugClientInfo { payload, control_handle } =
11969 self
11970 {
11971 Some((payload, control_handle))
11972 } else {
11973 None
11974 }
11975 }
11976
11977 #[allow(irrefutable_let_patterns)]
11978 pub fn into_set_debug_timeout_log_deadline(
11979 self,
11980 ) -> Option<(NodeSetDebugTimeoutLogDeadlineRequest, BufferCollectionTokenGroupControlHandle)>
11981 {
11982 if let BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {
11983 payload,
11984 control_handle,
11985 } = self
11986 {
11987 Some((payload, control_handle))
11988 } else {
11989 None
11990 }
11991 }
11992
11993 #[allow(irrefutable_let_patterns)]
11994 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
11995 if let BufferCollectionTokenGroupRequest::SetVerboseLogging { control_handle } = self {
11996 Some((control_handle))
11997 } else {
11998 None
11999 }
12000 }
12001
12002 #[allow(irrefutable_let_patterns)]
12003 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGroupGetNodeRefResponder)> {
12004 if let BufferCollectionTokenGroupRequest::GetNodeRef { responder } = self {
12005 Some((responder))
12006 } else {
12007 None
12008 }
12009 }
12010
12011 #[allow(irrefutable_let_patterns)]
12012 pub fn into_is_alternate_for(
12013 self,
12014 ) -> Option<(NodeIsAlternateForRequest, BufferCollectionTokenGroupIsAlternateForResponder)>
12015 {
12016 if let BufferCollectionTokenGroupRequest::IsAlternateFor { payload, responder } = self {
12017 Some((payload, responder))
12018 } else {
12019 None
12020 }
12021 }
12022
12023 #[allow(irrefutable_let_patterns)]
12024 pub fn into_get_buffer_collection_id(
12025 self,
12026 ) -> Option<(BufferCollectionTokenGroupGetBufferCollectionIdResponder)> {
12027 if let BufferCollectionTokenGroupRequest::GetBufferCollectionId { responder } = self {
12028 Some((responder))
12029 } else {
12030 None
12031 }
12032 }
12033
12034 #[allow(irrefutable_let_patterns)]
12035 pub fn into_set_weak(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
12036 if let BufferCollectionTokenGroupRequest::SetWeak { control_handle } = self {
12037 Some((control_handle))
12038 } else {
12039 None
12040 }
12041 }
12042
12043 #[allow(irrefutable_let_patterns)]
12044 pub fn into_set_weak_ok(
12045 self,
12046 ) -> Option<(NodeSetWeakOkRequest, BufferCollectionTokenGroupControlHandle)> {
12047 if let BufferCollectionTokenGroupRequest::SetWeakOk { payload, control_handle } = self {
12048 Some((payload, control_handle))
12049 } else {
12050 None
12051 }
12052 }
12053
12054 #[allow(irrefutable_let_patterns)]
12055 pub fn into_attach_node_tracking(
12056 self,
12057 ) -> Option<(NodeAttachNodeTrackingRequest, BufferCollectionTokenGroupControlHandle)> {
12058 if let BufferCollectionTokenGroupRequest::AttachNodeTracking { payload, control_handle } =
12059 self
12060 {
12061 Some((payload, control_handle))
12062 } else {
12063 None
12064 }
12065 }
12066
12067 #[allow(irrefutable_let_patterns)]
12068 pub fn into_create_child(
12069 self,
12070 ) -> Option<(
12071 BufferCollectionTokenGroupCreateChildRequest,
12072 BufferCollectionTokenGroupControlHandle,
12073 )> {
12074 if let BufferCollectionTokenGroupRequest::CreateChild { payload, control_handle } = self {
12075 Some((payload, control_handle))
12076 } else {
12077 None
12078 }
12079 }
12080
12081 #[allow(irrefutable_let_patterns)]
12082 pub fn into_create_children_sync(
12083 self,
12084 ) -> Option<(
12085 BufferCollectionTokenGroupCreateChildrenSyncRequest,
12086 BufferCollectionTokenGroupCreateChildrenSyncResponder,
12087 )> {
12088 if let BufferCollectionTokenGroupRequest::CreateChildrenSync { payload, responder } = self {
12089 Some((payload, responder))
12090 } else {
12091 None
12092 }
12093 }
12094
12095 #[allow(irrefutable_let_patterns)]
12096 pub fn into_all_children_present(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
12097 if let BufferCollectionTokenGroupRequest::AllChildrenPresent { control_handle } = self {
12098 Some((control_handle))
12099 } else {
12100 None
12101 }
12102 }
12103
12104 /// Name of the method defined in FIDL
12105 pub fn method_name(&self) -> &'static str {
12106 match *self {
12107 BufferCollectionTokenGroupRequest::Sync { .. } => "sync",
12108 BufferCollectionTokenGroupRequest::Release { .. } => "release",
12109 BufferCollectionTokenGroupRequest::SetName { .. } => "set_name",
12110 BufferCollectionTokenGroupRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
12111 BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline { .. } => {
12112 "set_debug_timeout_log_deadline"
12113 }
12114 BufferCollectionTokenGroupRequest::SetVerboseLogging { .. } => "set_verbose_logging",
12115 BufferCollectionTokenGroupRequest::GetNodeRef { .. } => "get_node_ref",
12116 BufferCollectionTokenGroupRequest::IsAlternateFor { .. } => "is_alternate_for",
12117 BufferCollectionTokenGroupRequest::GetBufferCollectionId { .. } => {
12118 "get_buffer_collection_id"
12119 }
12120 BufferCollectionTokenGroupRequest::SetWeak { .. } => "set_weak",
12121 BufferCollectionTokenGroupRequest::SetWeakOk { .. } => "set_weak_ok",
12122 BufferCollectionTokenGroupRequest::AttachNodeTracking { .. } => "attach_node_tracking",
12123 BufferCollectionTokenGroupRequest::CreateChild { .. } => "create_child",
12124 BufferCollectionTokenGroupRequest::CreateChildrenSync { .. } => "create_children_sync",
12125 BufferCollectionTokenGroupRequest::AllChildrenPresent { .. } => "all_children_present",
12126 BufferCollectionTokenGroupRequest::_UnknownMethod {
12127 method_type: fidl::MethodType::OneWay,
12128 ..
12129 } => "unknown one-way method",
12130 BufferCollectionTokenGroupRequest::_UnknownMethod {
12131 method_type: fidl::MethodType::TwoWay,
12132 ..
12133 } => "unknown two-way method",
12134 }
12135 }
12136}
12137
12138#[derive(Debug, Clone)]
12139pub struct BufferCollectionTokenGroupControlHandle {
12140 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
12141}
12142
12143impl fidl::endpoints::ControlHandle for BufferCollectionTokenGroupControlHandle {
12144 fn shutdown(&self) {
12145 self.inner.shutdown()
12146 }
12147
12148 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
12149 self.inner.shutdown_with_epitaph(status)
12150 }
12151
12152 fn is_closed(&self) -> bool {
12153 self.inner.channel().is_closed()
12154 }
12155 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
12156 self.inner.channel().on_closed()
12157 }
12158
12159 #[cfg(target_os = "fuchsia")]
12160 fn signal_peer(
12161 &self,
12162 clear_mask: zx::Signals,
12163 set_mask: zx::Signals,
12164 ) -> Result<(), zx_status::Status> {
12165 use fidl::Peered;
12166 self.inner.channel().signal_peer(clear_mask, set_mask)
12167 }
12168}
12169
12170impl BufferCollectionTokenGroupControlHandle {}
12171
12172#[must_use = "FIDL methods require a response to be sent"]
12173#[derive(Debug)]
12174pub struct BufferCollectionTokenGroupSyncResponder {
12175 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
12176 tx_id: u32,
12177}
12178
12179/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
12180/// if the responder is dropped without sending a response, so that the client
12181/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
12182impl std::ops::Drop for BufferCollectionTokenGroupSyncResponder {
12183 fn drop(&mut self) {
12184 self.control_handle.shutdown();
12185 // Safety: drops once, never accessed again
12186 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12187 }
12188}
12189
12190impl fidl::endpoints::Responder for BufferCollectionTokenGroupSyncResponder {
12191 type ControlHandle = BufferCollectionTokenGroupControlHandle;
12192
12193 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
12194 &self.control_handle
12195 }
12196
12197 fn drop_without_shutdown(mut self) {
12198 // Safety: drops once, never accessed again due to mem::forget
12199 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12200 // Prevent Drop from running (which would shut down the channel)
12201 std::mem::forget(self);
12202 }
12203}
12204
12205impl BufferCollectionTokenGroupSyncResponder {
12206 /// Sends a response to the FIDL transaction.
12207 ///
12208 /// Sets the channel to shutdown if an error occurs.
12209 pub fn send(self) -> Result<(), fidl::Error> {
12210 let _result = self.send_raw();
12211 if _result.is_err() {
12212 self.control_handle.shutdown();
12213 }
12214 self.drop_without_shutdown();
12215 _result
12216 }
12217
12218 /// Similar to "send" but does not shutdown the channel if an error occurs.
12219 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
12220 let _result = self.send_raw();
12221 self.drop_without_shutdown();
12222 _result
12223 }
12224
12225 fn send_raw(&self) -> Result<(), fidl::Error> {
12226 self.control_handle.inner.send::<fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>>(
12227 fidl::encoding::Flexible::new(()),
12228 self.tx_id,
12229 0x11ac2555cf575b54,
12230 fidl::encoding::DynamicFlags::FLEXIBLE,
12231 )
12232 }
12233}
12234
12235#[must_use = "FIDL methods require a response to be sent"]
12236#[derive(Debug)]
12237pub struct BufferCollectionTokenGroupGetNodeRefResponder {
12238 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
12239 tx_id: u32,
12240}
12241
12242/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
12243/// if the responder is dropped without sending a response, so that the client
12244/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
12245impl std::ops::Drop for BufferCollectionTokenGroupGetNodeRefResponder {
12246 fn drop(&mut self) {
12247 self.control_handle.shutdown();
12248 // Safety: drops once, never accessed again
12249 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12250 }
12251}
12252
12253impl fidl::endpoints::Responder for BufferCollectionTokenGroupGetNodeRefResponder {
12254 type ControlHandle = BufferCollectionTokenGroupControlHandle;
12255
12256 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
12257 &self.control_handle
12258 }
12259
12260 fn drop_without_shutdown(mut self) {
12261 // Safety: drops once, never accessed again due to mem::forget
12262 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12263 // Prevent Drop from running (which would shut down the channel)
12264 std::mem::forget(self);
12265 }
12266}
12267
12268impl BufferCollectionTokenGroupGetNodeRefResponder {
12269 /// Sends a response to the FIDL transaction.
12270 ///
12271 /// Sets the channel to shutdown if an error occurs.
12272 pub fn send(self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
12273 let _result = self.send_raw(payload);
12274 if _result.is_err() {
12275 self.control_handle.shutdown();
12276 }
12277 self.drop_without_shutdown();
12278 _result
12279 }
12280
12281 /// Similar to "send" but does not shutdown the channel if an error occurs.
12282 pub fn send_no_shutdown_on_err(
12283 self,
12284 mut payload: NodeGetNodeRefResponse,
12285 ) -> Result<(), fidl::Error> {
12286 let _result = self.send_raw(payload);
12287 self.drop_without_shutdown();
12288 _result
12289 }
12290
12291 fn send_raw(&self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
12292 self.control_handle.inner.send::<fidl::encoding::FlexibleType<NodeGetNodeRefResponse>>(
12293 fidl::encoding::Flexible::new(&mut payload),
12294 self.tx_id,
12295 0x5b3d0e51614df053,
12296 fidl::encoding::DynamicFlags::FLEXIBLE,
12297 )
12298 }
12299}
12300
12301#[must_use = "FIDL methods require a response to be sent"]
12302#[derive(Debug)]
12303pub struct BufferCollectionTokenGroupIsAlternateForResponder {
12304 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
12305 tx_id: u32,
12306}
12307
12308/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
12309/// if the responder is dropped without sending a response, so that the client
12310/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
12311impl std::ops::Drop for BufferCollectionTokenGroupIsAlternateForResponder {
12312 fn drop(&mut self) {
12313 self.control_handle.shutdown();
12314 // Safety: drops once, never accessed again
12315 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12316 }
12317}
12318
12319impl fidl::endpoints::Responder for BufferCollectionTokenGroupIsAlternateForResponder {
12320 type ControlHandle = BufferCollectionTokenGroupControlHandle;
12321
12322 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
12323 &self.control_handle
12324 }
12325
12326 fn drop_without_shutdown(mut self) {
12327 // Safety: drops once, never accessed again due to mem::forget
12328 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12329 // Prevent Drop from running (which would shut down the channel)
12330 std::mem::forget(self);
12331 }
12332}
12333
12334impl BufferCollectionTokenGroupIsAlternateForResponder {
12335 /// Sends a response to the FIDL transaction.
12336 ///
12337 /// Sets the channel to shutdown if an error occurs.
12338 pub fn send(
12339 self,
12340 mut result: Result<&NodeIsAlternateForResponse, Error>,
12341 ) -> Result<(), fidl::Error> {
12342 let _result = self.send_raw(result);
12343 if _result.is_err() {
12344 self.control_handle.shutdown();
12345 }
12346 self.drop_without_shutdown();
12347 _result
12348 }
12349
12350 /// Similar to "send" but does not shutdown the channel if an error occurs.
12351 pub fn send_no_shutdown_on_err(
12352 self,
12353 mut result: Result<&NodeIsAlternateForResponse, Error>,
12354 ) -> Result<(), fidl::Error> {
12355 let _result = self.send_raw(result);
12356 self.drop_without_shutdown();
12357 _result
12358 }
12359
12360 fn send_raw(
12361 &self,
12362 mut result: Result<&NodeIsAlternateForResponse, Error>,
12363 ) -> Result<(), fidl::Error> {
12364 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
12365 NodeIsAlternateForResponse,
12366 Error,
12367 >>(
12368 fidl::encoding::FlexibleResult::new(result),
12369 self.tx_id,
12370 0x3a58e00157e0825,
12371 fidl::encoding::DynamicFlags::FLEXIBLE,
12372 )
12373 }
12374}
12375
12376#[must_use = "FIDL methods require a response to be sent"]
12377#[derive(Debug)]
12378pub struct BufferCollectionTokenGroupGetBufferCollectionIdResponder {
12379 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
12380 tx_id: u32,
12381}
12382
12383/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
12384/// if the responder is dropped without sending a response, so that the client
12385/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
12386impl std::ops::Drop for BufferCollectionTokenGroupGetBufferCollectionIdResponder {
12387 fn drop(&mut self) {
12388 self.control_handle.shutdown();
12389 // Safety: drops once, never accessed again
12390 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12391 }
12392}
12393
12394impl fidl::endpoints::Responder for BufferCollectionTokenGroupGetBufferCollectionIdResponder {
12395 type ControlHandle = BufferCollectionTokenGroupControlHandle;
12396
12397 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
12398 &self.control_handle
12399 }
12400
12401 fn drop_without_shutdown(mut self) {
12402 // Safety: drops once, never accessed again due to mem::forget
12403 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12404 // Prevent Drop from running (which would shut down the channel)
12405 std::mem::forget(self);
12406 }
12407}
12408
12409impl BufferCollectionTokenGroupGetBufferCollectionIdResponder {
12410 /// Sends a response to the FIDL transaction.
12411 ///
12412 /// Sets the channel to shutdown if an error occurs.
12413 pub fn send(self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
12414 let _result = self.send_raw(payload);
12415 if _result.is_err() {
12416 self.control_handle.shutdown();
12417 }
12418 self.drop_without_shutdown();
12419 _result
12420 }
12421
12422 /// Similar to "send" but does not shutdown the channel if an error occurs.
12423 pub fn send_no_shutdown_on_err(
12424 self,
12425 mut payload: &NodeGetBufferCollectionIdResponse,
12426 ) -> Result<(), fidl::Error> {
12427 let _result = self.send_raw(payload);
12428 self.drop_without_shutdown();
12429 _result
12430 }
12431
12432 fn send_raw(&self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
12433 self.control_handle
12434 .inner
12435 .send::<fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>>(
12436 fidl::encoding::Flexible::new(payload),
12437 self.tx_id,
12438 0x77d19a494b78ba8c,
12439 fidl::encoding::DynamicFlags::FLEXIBLE,
12440 )
12441 }
12442}
12443
12444#[must_use = "FIDL methods require a response to be sent"]
12445#[derive(Debug)]
12446pub struct BufferCollectionTokenGroupCreateChildrenSyncResponder {
12447 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
12448 tx_id: u32,
12449}
12450
12451/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
12452/// if the responder is dropped without sending a response, so that the client
12453/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
12454impl std::ops::Drop for BufferCollectionTokenGroupCreateChildrenSyncResponder {
12455 fn drop(&mut self) {
12456 self.control_handle.shutdown();
12457 // Safety: drops once, never accessed again
12458 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12459 }
12460}
12461
12462impl fidl::endpoints::Responder for BufferCollectionTokenGroupCreateChildrenSyncResponder {
12463 type ControlHandle = BufferCollectionTokenGroupControlHandle;
12464
12465 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
12466 &self.control_handle
12467 }
12468
12469 fn drop_without_shutdown(mut self) {
12470 // Safety: drops once, never accessed again due to mem::forget
12471 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12472 // Prevent Drop from running (which would shut down the channel)
12473 std::mem::forget(self);
12474 }
12475}
12476
12477impl BufferCollectionTokenGroupCreateChildrenSyncResponder {
12478 /// Sends a response to the FIDL transaction.
12479 ///
12480 /// Sets the channel to shutdown if an error occurs.
12481 pub fn send(
12482 self,
12483 mut payload: BufferCollectionTokenGroupCreateChildrenSyncResponse,
12484 ) -> Result<(), fidl::Error> {
12485 let _result = self.send_raw(payload);
12486 if _result.is_err() {
12487 self.control_handle.shutdown();
12488 }
12489 self.drop_without_shutdown();
12490 _result
12491 }
12492
12493 /// Similar to "send" but does not shutdown the channel if an error occurs.
12494 pub fn send_no_shutdown_on_err(
12495 self,
12496 mut payload: BufferCollectionTokenGroupCreateChildrenSyncResponse,
12497 ) -> Result<(), fidl::Error> {
12498 let _result = self.send_raw(payload);
12499 self.drop_without_shutdown();
12500 _result
12501 }
12502
12503 fn send_raw(
12504 &self,
12505 mut payload: BufferCollectionTokenGroupCreateChildrenSyncResponse,
12506 ) -> Result<(), fidl::Error> {
12507 self.control_handle.inner.send::<fidl::encoding::FlexibleType<
12508 BufferCollectionTokenGroupCreateChildrenSyncResponse,
12509 >>(
12510 fidl::encoding::Flexible::new(&mut payload),
12511 self.tx_id,
12512 0x15dea448c536070a,
12513 fidl::encoding::DynamicFlags::FLEXIBLE,
12514 )
12515 }
12516}
12517
12518#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
12519pub struct NodeMarker;
12520
12521impl fidl::endpoints::ProtocolMarker for NodeMarker {
12522 type Proxy = NodeProxy;
12523 type RequestStream = NodeRequestStream;
12524 #[cfg(target_os = "fuchsia")]
12525 type SynchronousProxy = NodeSynchronousProxy;
12526
12527 const DEBUG_NAME: &'static str = "(anonymous) Node";
12528}
12529pub type NodeIsAlternateForResult = Result<NodeIsAlternateForResponse, Error>;
12530
12531pub trait NodeProxyInterface: Send + Sync {
12532 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
12533 fn r#sync(&self) -> Self::SyncResponseFut;
12534 fn r#release(&self) -> Result<(), fidl::Error>;
12535 fn r#set_name(&self, payload: &NodeSetNameRequest) -> Result<(), fidl::Error>;
12536 fn r#set_debug_client_info(
12537 &self,
12538 payload: &NodeSetDebugClientInfoRequest,
12539 ) -> Result<(), fidl::Error>;
12540 fn r#set_debug_timeout_log_deadline(
12541 &self,
12542 payload: &NodeSetDebugTimeoutLogDeadlineRequest,
12543 ) -> Result<(), fidl::Error>;
12544 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
12545 type GetNodeRefResponseFut: std::future::Future<Output = Result<NodeGetNodeRefResponse, fidl::Error>>
12546 + Send;
12547 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
12548 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
12549 + Send;
12550 fn r#is_alternate_for(
12551 &self,
12552 payload: NodeIsAlternateForRequest,
12553 ) -> Self::IsAlternateForResponseFut;
12554 type GetBufferCollectionIdResponseFut: std::future::Future<Output = Result<NodeGetBufferCollectionIdResponse, fidl::Error>>
12555 + Send;
12556 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut;
12557 fn r#set_weak(&self) -> Result<(), fidl::Error>;
12558 fn r#set_weak_ok(&self, payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error>;
12559 fn r#attach_node_tracking(
12560 &self,
12561 payload: NodeAttachNodeTrackingRequest,
12562 ) -> Result<(), fidl::Error>;
12563}
12564#[derive(Debug)]
12565#[cfg(target_os = "fuchsia")]
12566pub struct NodeSynchronousProxy {
12567 client: fidl::client::sync::Client,
12568}
12569
12570#[cfg(target_os = "fuchsia")]
12571impl fidl::endpoints::SynchronousProxy for NodeSynchronousProxy {
12572 type Proxy = NodeProxy;
12573 type Protocol = NodeMarker;
12574
12575 fn from_channel(inner: fidl::Channel) -> Self {
12576 Self::new(inner)
12577 }
12578
12579 fn into_channel(self) -> fidl::Channel {
12580 self.client.into_channel()
12581 }
12582
12583 fn as_channel(&self) -> &fidl::Channel {
12584 self.client.as_channel()
12585 }
12586}
12587
12588#[cfg(target_os = "fuchsia")]
12589impl NodeSynchronousProxy {
12590 pub fn new(channel: fidl::Channel) -> Self {
12591 Self { client: fidl::client::sync::Client::new(channel) }
12592 }
12593
12594 pub fn into_channel(self) -> fidl::Channel {
12595 self.client.into_channel()
12596 }
12597
12598 /// Waits until an event arrives and returns it. It is safe for other
12599 /// threads to make concurrent requests while waiting for an event.
12600 pub fn wait_for_event(&self, deadline: zx::MonotonicInstant) -> Result<NodeEvent, fidl::Error> {
12601 NodeEvent::decode(self.client.wait_for_event::<NodeMarker>(deadline)?)
12602 }
12603
12604 /// Ensure that previous messages have been received server side. This is
12605 /// particularly useful after previous messages that created new tokens,
12606 /// because a token must be known to the sysmem server before sending the
12607 /// token to another participant.
12608 ///
12609 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
12610 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
12611 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
12612 /// to mitigate the possibility of a hostile/fake
12613 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
12614 /// Another way is to pass the token to
12615 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
12616 /// the token as part of exchanging it for a
12617 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
12618 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
12619 /// of stalling.
12620 ///
12621 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
12622 /// and then starting and completing a `Sync`, it's then safe to send the
12623 /// `BufferCollectionToken` client ends to other participants knowing the
12624 /// server will recognize the tokens when they're sent by the other
12625 /// participants to sysmem in a
12626 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
12627 /// efficient way to create tokens while avoiding unnecessary round trips.
12628 ///
12629 /// Other options include waiting for each
12630 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
12631 /// individually (using separate call to `Sync` after each), or calling
12632 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
12633 /// converted to a `BufferCollection` via
12634 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
12635 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
12636 /// the sync step and can create multiple tokens at once.
12637 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
12638 let _response = self.client.send_query::<
12639 fidl::encoding::EmptyPayload,
12640 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
12641 NodeMarker,
12642 >(
12643 (),
12644 0x11ac2555cf575b54,
12645 fidl::encoding::DynamicFlags::FLEXIBLE,
12646 ___deadline,
12647 )?
12648 .into_result::<NodeMarker>("sync")?;
12649 Ok(_response)
12650 }
12651
12652 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
12653 ///
12654 /// Normally a participant will convert a `BufferCollectionToken` into a
12655 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
12656 /// `Release` via the token (and then close the channel immediately or
12657 /// shortly later in response to server closing the server end), which
12658 /// avoids causing buffer collection failure. Without a prior `Release`,
12659 /// closing the `BufferCollectionToken` client end will cause buffer
12660 /// collection failure.
12661 ///
12662 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
12663 ///
12664 /// By default the server handles unexpected closure of a
12665 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
12666 /// first) by failing the buffer collection. Partly this is to expedite
12667 /// closing VMO handles to reclaim memory when any participant fails. If a
12668 /// participant would like to cleanly close a `BufferCollection` without
12669 /// causing buffer collection failure, the participant can send `Release`
12670 /// before closing the `BufferCollection` client end. The `Release` can
12671 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
12672 /// buffer collection won't require constraints from this node in order to
12673 /// allocate. If after `SetConstraints`, the constraints are retained and
12674 /// aggregated, despite the lack of `BufferCollection` connection at the
12675 /// time of constraints aggregation.
12676 ///
12677 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
12678 ///
12679 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
12680 /// end (without `Release` first) will trigger failure of the buffer
12681 /// collection. To close a `BufferCollectionTokenGroup` channel without
12682 /// failing the buffer collection, ensure that AllChildrenPresent() has been
12683 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
12684 /// client end.
12685 ///
12686 /// If `Release` occurs before
12687 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
12688 /// buffer collection will fail (triggered by reception of `Release` without
12689 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
12690 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
12691 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
12692 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
12693 /// close requires `AllChildrenPresent` (if not already sent), then
12694 /// `Release`, then close client end.
12695 ///
12696 /// If `Release` occurs after `AllChildrenPresent`, the children and all
12697 /// their constraints remain intact (just as they would if the
12698 /// `BufferCollectionTokenGroup` channel had remained open), and the client
12699 /// end close doesn't trigger buffer collection failure.
12700 ///
12701 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
12702 ///
12703 /// For brevity, the per-channel-protocol paragraphs above ignore the
12704 /// separate failure domain created by
12705 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
12706 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
12707 /// unexpectedly closes (without `Release` first) and that client end is
12708 /// under a failure domain, instead of failing the whole buffer collection,
12709 /// the failure domain is failed, but the buffer collection itself is
12710 /// isolated from failure of the failure domain. Such failure domains can be
12711 /// nested, in which case only the inner-most failure domain in which the
12712 /// `Node` resides fails.
12713 pub fn r#release(&self) -> Result<(), fidl::Error> {
12714 self.client.send::<fidl::encoding::EmptyPayload>(
12715 (),
12716 0x6a5cae7d6d6e04c6,
12717 fidl::encoding::DynamicFlags::FLEXIBLE,
12718 )
12719 }
12720
12721 /// Set a name for VMOs in this buffer collection.
12722 ///
12723 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
12724 /// will be truncated to fit. The name of the vmo will be suffixed with the
12725 /// buffer index within the collection (if the suffix fits within
12726 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
12727 /// listed in the inspect data.
12728 ///
12729 /// The name only affects VMOs allocated after the name is set; this call
12730 /// does not rename existing VMOs. If multiple clients set different names
12731 /// then the larger priority value will win. Setting a new name with the
12732 /// same priority as a prior name doesn't change the name.
12733 ///
12734 /// All table fields are currently required.
12735 ///
12736 /// + request `priority` The name is only set if this is the first `SetName`
12737 /// or if `priority` is greater than any previous `priority` value in
12738 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
12739 /// + request `name` The name for VMOs created under this buffer collection.
12740 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
12741 self.client.send::<NodeSetNameRequest>(
12742 payload,
12743 0xb41f1624f48c1e9,
12744 fidl::encoding::DynamicFlags::FLEXIBLE,
12745 )
12746 }
12747
12748 /// Set information about the current client that can be used by sysmem to
12749 /// help diagnose leaking memory and allocation stalls waiting for a
12750 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
12751 ///
12752 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
12753 /// `Node`(s) derived from this `Node`, unless overriden by
12754 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
12755 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
12756 ///
12757 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
12758 /// `Allocator` is the most efficient way to ensure that all
12759 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
12760 /// set, and is also more efficient than separately sending the same debug
12761 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
12762 /// created [`fuchsia.sysmem2/Node`].
12763 ///
12764 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
12765 /// indicate which client is closing their channel first, leading to subtree
12766 /// failure (which can be normal if the purpose of the subtree is over, but
12767 /// if happening earlier than expected, the client-channel-specific name can
12768 /// help diagnose where the failure is first coming from, from sysmem's
12769 /// point of view).
12770 ///
12771 /// All table fields are currently required.
12772 ///
12773 /// + request `name` This can be an arbitrary string, but the current
12774 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
12775 /// + request `id` This can be an arbitrary id, but the current process ID
12776 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
12777 pub fn r#set_debug_client_info(
12778 &self,
12779 mut payload: &NodeSetDebugClientInfoRequest,
12780 ) -> Result<(), fidl::Error> {
12781 self.client.send::<NodeSetDebugClientInfoRequest>(
12782 payload,
12783 0x5cde8914608d99b1,
12784 fidl::encoding::DynamicFlags::FLEXIBLE,
12785 )
12786 }
12787
12788 /// Sysmem logs a warning if sysmem hasn't seen
12789 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
12790 /// within 5 seconds after creation of a new collection.
12791 ///
12792 /// Clients can call this method to change when the log is printed. If
12793 /// multiple client set the deadline, it's unspecified which deadline will
12794 /// take effect.
12795 ///
12796 /// In most cases the default works well.
12797 ///
12798 /// All table fields are currently required.
12799 ///
12800 /// + request `deadline` The time at which sysmem will start trying to log
12801 /// the warning, unless all constraints are with sysmem by then.
12802 pub fn r#set_debug_timeout_log_deadline(
12803 &self,
12804 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
12805 ) -> Result<(), fidl::Error> {
12806 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
12807 payload,
12808 0x716b0af13d5c0806,
12809 fidl::encoding::DynamicFlags::FLEXIBLE,
12810 )
12811 }
12812
12813 /// This enables verbose logging for the buffer collection.
12814 ///
12815 /// Verbose logging includes constraints set via
12816 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
12817 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
12818 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
12819 /// the tree of `Node`(s).
12820 ///
12821 /// Normally sysmem prints only a single line complaint when aggregation
12822 /// fails, with just the specific detailed reason that aggregation failed,
12823 /// with little surrounding context. While this is often enough to diagnose
12824 /// a problem if only a small change was made and everything was working
12825 /// before the small change, it's often not particularly helpful for getting
12826 /// a new buffer collection to work for the first time. Especially with
12827 /// more complex trees of nodes, involving things like
12828 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
12829 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
12830 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
12831 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
12832 /// looks like and why it's failing a logical allocation, or why a tree or
12833 /// subtree is failing sooner than expected.
12834 ///
12835 /// The intent of the extra logging is to be acceptable from a performance
12836 /// point of view, under the assumption that verbose logging is only enabled
12837 /// on a low number of buffer collections. If we're not tracking down a bug,
12838 /// we shouldn't send this message.
12839 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
12840 self.client.send::<fidl::encoding::EmptyPayload>(
12841 (),
12842 0x5209c77415b4dfad,
12843 fidl::encoding::DynamicFlags::FLEXIBLE,
12844 )
12845 }
12846
12847 /// This gets a handle that can be used as a parameter to
12848 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
12849 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
12850 /// client obtained this handle from this `Node`.
12851 ///
12852 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
12853 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
12854 /// despite the two calls typically being on different channels.
12855 ///
12856 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
12857 ///
12858 /// All table fields are currently required.
12859 ///
12860 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
12861 /// different `Node` channel, to prove that the client obtained the handle
12862 /// from this `Node`.
12863 pub fn r#get_node_ref(
12864 &self,
12865 ___deadline: zx::MonotonicInstant,
12866 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
12867 let _response = self.client.send_query::<
12868 fidl::encoding::EmptyPayload,
12869 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
12870 NodeMarker,
12871 >(
12872 (),
12873 0x5b3d0e51614df053,
12874 fidl::encoding::DynamicFlags::FLEXIBLE,
12875 ___deadline,
12876 )?
12877 .into_result::<NodeMarker>("get_node_ref")?;
12878 Ok(_response)
12879 }
12880
12881 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
12882 /// rooted at a different child token of a common parent
12883 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
12884 /// passed-in `node_ref`.
12885 ///
12886 /// This call is for assisting with admission control de-duplication, and
12887 /// with debugging.
12888 ///
12889 /// The `node_ref` must be obtained using
12890 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
12891 ///
12892 /// The `node_ref` can be a duplicated handle; it's not necessary to call
12893 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
12894 ///
12895 /// If a calling token may not actually be a valid token at all due to a
12896 /// potentially hostile/untrusted provider of the token, call
12897 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
12898 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
12899 /// never responds due to a calling token not being a real token (not really
12900 /// talking to sysmem). Another option is to call
12901 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
12902 /// which also validates the token along with converting it to a
12903 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
12904 ///
12905 /// All table fields are currently required.
12906 ///
12907 /// - response `is_alternate`
12908 /// - true: The first parent node in common between the calling node and
12909 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
12910 /// that the calling `Node` and the `node_ref` `Node` will not have both
12911 /// their constraints apply - rather sysmem will choose one or the other
12912 /// of the constraints - never both. This is because only one child of
12913 /// a `BufferCollectionTokenGroup` is selected during logical
12914 /// allocation, with only that one child's subtree contributing to
12915 /// constraints aggregation.
12916 /// - false: The first parent node in common between the calling `Node`
12917 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
12918 /// Currently, this means the first parent node in common is a
12919 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
12920 /// `Release`ed). This means that the calling `Node` and the `node_ref`
12921 /// `Node` may have both their constraints apply during constraints
12922 /// aggregation of the logical allocation, if both `Node`(s) are
12923 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
12924 /// this case, there is no `BufferCollectionTokenGroup` that will
12925 /// directly prevent the two `Node`(s) from both being selected and
12926 /// their constraints both aggregated, but even when false, one or both
12927 /// `Node`(s) may still be eliminated from consideration if one or both
12928 /// `Node`(s) has a direct or indirect parent
12929 /// `BufferCollectionTokenGroup` which selects a child subtree other
12930 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
12931 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
12932 /// associated with the same buffer collection as the calling `Node`.
12933 /// Another reason for this error is if the `node_ref` is an
12934 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
12935 /// a real `node_ref` obtained from `GetNodeRef`.
12936 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
12937 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
12938 /// the needed rights expected on a real `node_ref`.
12939 /// * No other failing status codes are returned by this call. However,
12940 /// sysmem may add additional codes in future, so the client should have
12941 /// sensible default handling for any failing status code.
12942 pub fn r#is_alternate_for(
12943 &self,
12944 mut payload: NodeIsAlternateForRequest,
12945 ___deadline: zx::MonotonicInstant,
12946 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
12947 let _response = self.client.send_query::<
12948 NodeIsAlternateForRequest,
12949 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
12950 NodeMarker,
12951 >(
12952 &mut payload,
12953 0x3a58e00157e0825,
12954 fidl::encoding::DynamicFlags::FLEXIBLE,
12955 ___deadline,
12956 )?
12957 .into_result::<NodeMarker>("is_alternate_for")?;
12958 Ok(_response.map(|x| x))
12959 }
12960
12961 /// Get the buffer collection ID. This ID is also available from
12962 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
12963 /// within the collection).
12964 ///
12965 /// This call is mainly useful in situations where we can't convey a
12966 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
12967 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
12968 /// handle, which can be joined back up with a `BufferCollection` client end
12969 /// that was created via a different path. Prefer to convey a
12970 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
12971 ///
12972 /// Trusting a `buffer_collection_id` value from a source other than sysmem
12973 /// is analogous to trusting a koid value from a source other than zircon.
12974 /// Both should be avoided unless really necessary, and both require
12975 /// caution. In some situations it may be reasonable to refer to a
12976 /// pre-established `BufferCollection` by `buffer_collection_id` via a
12977 /// protocol for efficiency reasons, but an incoming value purporting to be
12978 /// a `buffer_collection_id` is not sufficient alone to justify granting the
12979 /// sender of the `buffer_collection_id` any capability. The sender must
12980 /// first prove to a receiver that the sender has/had a VMO or has/had a
12981 /// `BufferCollectionToken` to the same collection by sending a handle that
12982 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
12983 /// `buffer_collection_id` value. The receiver should take care to avoid
12984 /// assuming that a sender had a `BufferCollectionToken` in cases where the
12985 /// sender has only proven that the sender had a VMO.
12986 ///
12987 /// - response `buffer_collection_id` This ID is unique per buffer
12988 /// collection per boot. Each buffer is uniquely identified by the
12989 /// `buffer_collection_id` and `buffer_index` together.
12990 pub fn r#get_buffer_collection_id(
12991 &self,
12992 ___deadline: zx::MonotonicInstant,
12993 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
12994 let _response = self.client.send_query::<
12995 fidl::encoding::EmptyPayload,
12996 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
12997 NodeMarker,
12998 >(
12999 (),
13000 0x77d19a494b78ba8c,
13001 fidl::encoding::DynamicFlags::FLEXIBLE,
13002 ___deadline,
13003 )?
13004 .into_result::<NodeMarker>("get_buffer_collection_id")?;
13005 Ok(_response)
13006 }
13007
13008 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
13009 /// created after this message to weak, which means that a client's `Node`
13010 /// client end (or a child created after this message) is not alone
13011 /// sufficient to keep allocated VMOs alive.
13012 ///
13013 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
13014 /// `close_weak_asap`.
13015 ///
13016 /// This message is only permitted before the `Node` becomes ready for
13017 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
13018 /// * `BufferCollectionToken`: any time
13019 /// * `BufferCollection`: before `SetConstraints`
13020 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
13021 ///
13022 /// Currently, no conversion from strong `Node` to weak `Node` after ready
13023 /// for allocation is provided, but a client can simulate that by creating
13024 /// an additional `Node` before allocation and setting that additional
13025 /// `Node` to weak, and then potentially at some point later sending
13026 /// `Release` and closing the client end of the client's strong `Node`, but
13027 /// keeping the client's weak `Node`.
13028 ///
13029 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
13030 /// collection failure (all `Node` client end(s) will see
13031 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
13032 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
13033 /// this situation until all `Node`(s) are ready for allocation. For initial
13034 /// allocation to succeed, at least one strong `Node` is required to exist
13035 /// at allocation time, but after that client receives VMO handles, that
13036 /// client can `BufferCollection.Release` and close the client end without
13037 /// causing this type of failure.
13038 ///
13039 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
13040 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
13041 /// separately as appropriate.
13042 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
13043 self.client.send::<fidl::encoding::EmptyPayload>(
13044 (),
13045 0x22dd3ea514eeffe1,
13046 fidl::encoding::DynamicFlags::FLEXIBLE,
13047 )
13048 }
13049
13050 /// This indicates to sysmem that the client is prepared to pay attention to
13051 /// `close_weak_asap`.
13052 ///
13053 /// If sent, this message must be before
13054 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
13055 ///
13056 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
13057 /// send this message before `WaitForAllBuffersAllocated`, or a parent
13058 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
13059 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
13060 /// trigger buffer collection failure.
13061 ///
13062 /// This message is necessary because weak sysmem VMOs have not always been
13063 /// a thing, so older clients are not aware of the need to pay attention to
13064 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
13065 /// sysmem weak VMO handles asap. By having this message and requiring
13066 /// participants to indicate their acceptance of this aspect of the overall
13067 /// protocol, we avoid situations where an older client is delivered a weak
13068 /// VMO without any way for sysmem to get that VMO to close quickly later
13069 /// (and on a per-buffer basis).
13070 ///
13071 /// A participant that doesn't handle `close_weak_asap` and also doesn't
13072 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
13073 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
13074 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
13075 /// same participant has a child/delegate which does retrieve VMOs, that
13076 /// child/delegate will need to send `SetWeakOk` before
13077 /// `WaitForAllBuffersAllocated`.
13078 ///
13079 /// + request `for_child_nodes_also` If present and true, this means direct
13080 /// child nodes of this node created after this message plus all
13081 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
13082 /// those nodes. Any child node of this node that was created before this
13083 /// message is not included. This setting is "sticky" in the sense that a
13084 /// subsequent `SetWeakOk` without this bool set to true does not reset
13085 /// the server-side bool. If this creates a problem for a participant, a
13086 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
13087 /// tokens instead, as appropriate. A participant should only set
13088 /// `for_child_nodes_also` true if the participant can really promise to
13089 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
13090 /// weak VMO handles held by participants holding the corresponding child
13091 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
13092 /// which are using sysmem(1) can be weak, despite the clients of those
13093 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
13094 /// direct way to find out about `close_weak_asap`. This only applies to
13095 /// descendents of this `Node` which are using sysmem(1), not to this
13096 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
13097 /// token, which will fail allocation unless an ancestor of this `Node`
13098 /// specified `for_child_nodes_also` true.
13099 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
13100 self.client.send::<NodeSetWeakOkRequest>(
13101 &mut payload,
13102 0x38a44fc4d7724be9,
13103 fidl::encoding::DynamicFlags::FLEXIBLE,
13104 )
13105 }
13106
13107 /// The server_end will be closed after this `Node` and any child nodes have
13108 /// have released their buffer counts, making those counts available for
13109 /// reservation by a different `Node` via
13110 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
13111 ///
13112 /// The `Node` buffer counts may not be released until the entire tree of
13113 /// `Node`(s) is closed or failed, because
13114 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
13115 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
13116 /// `Node` buffer counts remain reserved until the orphaned node is later
13117 /// cleaned up.
13118 ///
13119 /// If the `Node` exceeds a fairly large number of attached eventpair server
13120 /// ends, a log message will indicate this and the `Node` (and the
13121 /// appropriate) sub-tree will fail.
13122 ///
13123 /// The `server_end` will remain open when
13124 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
13125 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
13126 /// [`fuchsia.sysmem2/BufferCollection`].
13127 ///
13128 /// This message can also be used with a
13129 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
13130 pub fn r#attach_node_tracking(
13131 &self,
13132 mut payload: NodeAttachNodeTrackingRequest,
13133 ) -> Result<(), fidl::Error> {
13134 self.client.send::<NodeAttachNodeTrackingRequest>(
13135 &mut payload,
13136 0x3f22f2a293d3cdac,
13137 fidl::encoding::DynamicFlags::FLEXIBLE,
13138 )
13139 }
13140}
13141
13142#[cfg(target_os = "fuchsia")]
13143impl From<NodeSynchronousProxy> for zx::NullableHandle {
13144 fn from(value: NodeSynchronousProxy) -> Self {
13145 value.into_channel().into()
13146 }
13147}
13148
13149#[cfg(target_os = "fuchsia")]
13150impl From<fidl::Channel> for NodeSynchronousProxy {
13151 fn from(value: fidl::Channel) -> Self {
13152 Self::new(value)
13153 }
13154}
13155
13156#[cfg(target_os = "fuchsia")]
13157impl fidl::endpoints::FromClient for NodeSynchronousProxy {
13158 type Protocol = NodeMarker;
13159
13160 fn from_client(value: fidl::endpoints::ClientEnd<NodeMarker>) -> Self {
13161 Self::new(value.into_channel())
13162 }
13163}
13164
13165#[derive(Debug, Clone)]
13166pub struct NodeProxy {
13167 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
13168}
13169
13170impl fidl::endpoints::Proxy for NodeProxy {
13171 type Protocol = NodeMarker;
13172
13173 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
13174 Self::new(inner)
13175 }
13176
13177 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
13178 self.client.into_channel().map_err(|client| Self { client })
13179 }
13180
13181 fn as_channel(&self) -> &::fidl::AsyncChannel {
13182 self.client.as_channel()
13183 }
13184}
13185
13186impl NodeProxy {
13187 /// Create a new Proxy for fuchsia.sysmem2/Node.
13188 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
13189 let protocol_name = <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
13190 Self { client: fidl::client::Client::new(channel, protocol_name) }
13191 }
13192
13193 /// Get a Stream of events from the remote end of the protocol.
13194 ///
13195 /// # Panics
13196 ///
13197 /// Panics if the event stream was already taken.
13198 pub fn take_event_stream(&self) -> NodeEventStream {
13199 NodeEventStream { event_receiver: self.client.take_event_receiver() }
13200 }
13201
13202 /// Ensure that previous messages have been received server side. This is
13203 /// particularly useful after previous messages that created new tokens,
13204 /// because a token must be known to the sysmem server before sending the
13205 /// token to another participant.
13206 ///
13207 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
13208 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
13209 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
13210 /// to mitigate the possibility of a hostile/fake
13211 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
13212 /// Another way is to pass the token to
13213 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
13214 /// the token as part of exchanging it for a
13215 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
13216 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
13217 /// of stalling.
13218 ///
13219 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
13220 /// and then starting and completing a `Sync`, it's then safe to send the
13221 /// `BufferCollectionToken` client ends to other participants knowing the
13222 /// server will recognize the tokens when they're sent by the other
13223 /// participants to sysmem in a
13224 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
13225 /// efficient way to create tokens while avoiding unnecessary round trips.
13226 ///
13227 /// Other options include waiting for each
13228 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
13229 /// individually (using separate call to `Sync` after each), or calling
13230 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
13231 /// converted to a `BufferCollection` via
13232 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
13233 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
13234 /// the sync step and can create multiple tokens at once.
13235 pub fn r#sync(
13236 &self,
13237 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
13238 NodeProxyInterface::r#sync(self)
13239 }
13240
13241 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
13242 ///
13243 /// Normally a participant will convert a `BufferCollectionToken` into a
13244 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
13245 /// `Release` via the token (and then close the channel immediately or
13246 /// shortly later in response to server closing the server end), which
13247 /// avoids causing buffer collection failure. Without a prior `Release`,
13248 /// closing the `BufferCollectionToken` client end will cause buffer
13249 /// collection failure.
13250 ///
13251 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
13252 ///
13253 /// By default the server handles unexpected closure of a
13254 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
13255 /// first) by failing the buffer collection. Partly this is to expedite
13256 /// closing VMO handles to reclaim memory when any participant fails. If a
13257 /// participant would like to cleanly close a `BufferCollection` without
13258 /// causing buffer collection failure, the participant can send `Release`
13259 /// before closing the `BufferCollection` client end. The `Release` can
13260 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
13261 /// buffer collection won't require constraints from this node in order to
13262 /// allocate. If after `SetConstraints`, the constraints are retained and
13263 /// aggregated, despite the lack of `BufferCollection` connection at the
13264 /// time of constraints aggregation.
13265 ///
13266 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
13267 ///
13268 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
13269 /// end (without `Release` first) will trigger failure of the buffer
13270 /// collection. To close a `BufferCollectionTokenGroup` channel without
13271 /// failing the buffer collection, ensure that AllChildrenPresent() has been
13272 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
13273 /// client end.
13274 ///
13275 /// If `Release` occurs before
13276 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
13277 /// buffer collection will fail (triggered by reception of `Release` without
13278 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
13279 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
13280 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
13281 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
13282 /// close requires `AllChildrenPresent` (if not already sent), then
13283 /// `Release`, then close client end.
13284 ///
13285 /// If `Release` occurs after `AllChildrenPresent`, the children and all
13286 /// their constraints remain intact (just as they would if the
13287 /// `BufferCollectionTokenGroup` channel had remained open), and the client
13288 /// end close doesn't trigger buffer collection failure.
13289 ///
13290 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
13291 ///
13292 /// For brevity, the per-channel-protocol paragraphs above ignore the
13293 /// separate failure domain created by
13294 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
13295 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
13296 /// unexpectedly closes (without `Release` first) and that client end is
13297 /// under a failure domain, instead of failing the whole buffer collection,
13298 /// the failure domain is failed, but the buffer collection itself is
13299 /// isolated from failure of the failure domain. Such failure domains can be
13300 /// nested, in which case only the inner-most failure domain in which the
13301 /// `Node` resides fails.
13302 pub fn r#release(&self) -> Result<(), fidl::Error> {
13303 NodeProxyInterface::r#release(self)
13304 }
13305
13306 /// Set a name for VMOs in this buffer collection.
13307 ///
13308 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
13309 /// will be truncated to fit. The name of the vmo will be suffixed with the
13310 /// buffer index within the collection (if the suffix fits within
13311 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
13312 /// listed in the inspect data.
13313 ///
13314 /// The name only affects VMOs allocated after the name is set; this call
13315 /// does not rename existing VMOs. If multiple clients set different names
13316 /// then the larger priority value will win. Setting a new name with the
13317 /// same priority as a prior name doesn't change the name.
13318 ///
13319 /// All table fields are currently required.
13320 ///
13321 /// + request `priority` The name is only set if this is the first `SetName`
13322 /// or if `priority` is greater than any previous `priority` value in
13323 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
13324 /// + request `name` The name for VMOs created under this buffer collection.
13325 pub fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
13326 NodeProxyInterface::r#set_name(self, payload)
13327 }
13328
13329 /// Set information about the current client that can be used by sysmem to
13330 /// help diagnose leaking memory and allocation stalls waiting for a
13331 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
13332 ///
13333 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
13334 /// `Node`(s) derived from this `Node`, unless overriden by
13335 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
13336 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
13337 ///
13338 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
13339 /// `Allocator` is the most efficient way to ensure that all
13340 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
13341 /// set, and is also more efficient than separately sending the same debug
13342 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
13343 /// created [`fuchsia.sysmem2/Node`].
13344 ///
13345 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
13346 /// indicate which client is closing their channel first, leading to subtree
13347 /// failure (which can be normal if the purpose of the subtree is over, but
13348 /// if happening earlier than expected, the client-channel-specific name can
13349 /// help diagnose where the failure is first coming from, from sysmem's
13350 /// point of view).
13351 ///
13352 /// All table fields are currently required.
13353 ///
13354 /// + request `name` This can be an arbitrary string, but the current
13355 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
13356 /// + request `id` This can be an arbitrary id, but the current process ID
13357 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
13358 pub fn r#set_debug_client_info(
13359 &self,
13360 mut payload: &NodeSetDebugClientInfoRequest,
13361 ) -> Result<(), fidl::Error> {
13362 NodeProxyInterface::r#set_debug_client_info(self, payload)
13363 }
13364
13365 /// Sysmem logs a warning if sysmem hasn't seen
13366 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
13367 /// within 5 seconds after creation of a new collection.
13368 ///
13369 /// Clients can call this method to change when the log is printed. If
13370 /// multiple client set the deadline, it's unspecified which deadline will
13371 /// take effect.
13372 ///
13373 /// In most cases the default works well.
13374 ///
13375 /// All table fields are currently required.
13376 ///
13377 /// + request `deadline` The time at which sysmem will start trying to log
13378 /// the warning, unless all constraints are with sysmem by then.
13379 pub fn r#set_debug_timeout_log_deadline(
13380 &self,
13381 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
13382 ) -> Result<(), fidl::Error> {
13383 NodeProxyInterface::r#set_debug_timeout_log_deadline(self, payload)
13384 }
13385
13386 /// This enables verbose logging for the buffer collection.
13387 ///
13388 /// Verbose logging includes constraints set via
13389 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
13390 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
13391 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
13392 /// the tree of `Node`(s).
13393 ///
13394 /// Normally sysmem prints only a single line complaint when aggregation
13395 /// fails, with just the specific detailed reason that aggregation failed,
13396 /// with little surrounding context. While this is often enough to diagnose
13397 /// a problem if only a small change was made and everything was working
13398 /// before the small change, it's often not particularly helpful for getting
13399 /// a new buffer collection to work for the first time. Especially with
13400 /// more complex trees of nodes, involving things like
13401 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
13402 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
13403 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
13404 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
13405 /// looks like and why it's failing a logical allocation, or why a tree or
13406 /// subtree is failing sooner than expected.
13407 ///
13408 /// The intent of the extra logging is to be acceptable from a performance
13409 /// point of view, under the assumption that verbose logging is only enabled
13410 /// on a low number of buffer collections. If we're not tracking down a bug,
13411 /// we shouldn't send this message.
13412 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
13413 NodeProxyInterface::r#set_verbose_logging(self)
13414 }
13415
13416 /// This gets a handle that can be used as a parameter to
13417 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
13418 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
13419 /// client obtained this handle from this `Node`.
13420 ///
13421 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
13422 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
13423 /// despite the two calls typically being on different channels.
13424 ///
13425 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
13426 ///
13427 /// All table fields are currently required.
13428 ///
13429 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
13430 /// different `Node` channel, to prove that the client obtained the handle
13431 /// from this `Node`.
13432 pub fn r#get_node_ref(
13433 &self,
13434 ) -> fidl::client::QueryResponseFut<
13435 NodeGetNodeRefResponse,
13436 fidl::encoding::DefaultFuchsiaResourceDialect,
13437 > {
13438 NodeProxyInterface::r#get_node_ref(self)
13439 }
13440
13441 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
13442 /// rooted at a different child token of a common parent
13443 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
13444 /// passed-in `node_ref`.
13445 ///
13446 /// This call is for assisting with admission control de-duplication, and
13447 /// with debugging.
13448 ///
13449 /// The `node_ref` must be obtained using
13450 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
13451 ///
13452 /// The `node_ref` can be a duplicated handle; it's not necessary to call
13453 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
13454 ///
13455 /// If a calling token may not actually be a valid token at all due to a
13456 /// potentially hostile/untrusted provider of the token, call
13457 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
13458 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
13459 /// never responds due to a calling token not being a real token (not really
13460 /// talking to sysmem). Another option is to call
13461 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
13462 /// which also validates the token along with converting it to a
13463 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
13464 ///
13465 /// All table fields are currently required.
13466 ///
13467 /// - response `is_alternate`
13468 /// - true: The first parent node in common between the calling node and
13469 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
13470 /// that the calling `Node` and the `node_ref` `Node` will not have both
13471 /// their constraints apply - rather sysmem will choose one or the other
13472 /// of the constraints - never both. This is because only one child of
13473 /// a `BufferCollectionTokenGroup` is selected during logical
13474 /// allocation, with only that one child's subtree contributing to
13475 /// constraints aggregation.
13476 /// - false: The first parent node in common between the calling `Node`
13477 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
13478 /// Currently, this means the first parent node in common is a
13479 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
13480 /// `Release`ed). This means that the calling `Node` and the `node_ref`
13481 /// `Node` may have both their constraints apply during constraints
13482 /// aggregation of the logical allocation, if both `Node`(s) are
13483 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
13484 /// this case, there is no `BufferCollectionTokenGroup` that will
13485 /// directly prevent the two `Node`(s) from both being selected and
13486 /// their constraints both aggregated, but even when false, one or both
13487 /// `Node`(s) may still be eliminated from consideration if one or both
13488 /// `Node`(s) has a direct or indirect parent
13489 /// `BufferCollectionTokenGroup` which selects a child subtree other
13490 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
13491 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
13492 /// associated with the same buffer collection as the calling `Node`.
13493 /// Another reason for this error is if the `node_ref` is an
13494 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
13495 /// a real `node_ref` obtained from `GetNodeRef`.
13496 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
13497 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
13498 /// the needed rights expected on a real `node_ref`.
13499 /// * No other failing status codes are returned by this call. However,
13500 /// sysmem may add additional codes in future, so the client should have
13501 /// sensible default handling for any failing status code.
13502 pub fn r#is_alternate_for(
13503 &self,
13504 mut payload: NodeIsAlternateForRequest,
13505 ) -> fidl::client::QueryResponseFut<
13506 NodeIsAlternateForResult,
13507 fidl::encoding::DefaultFuchsiaResourceDialect,
13508 > {
13509 NodeProxyInterface::r#is_alternate_for(self, payload)
13510 }
13511
13512 /// Get the buffer collection ID. This ID is also available from
13513 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
13514 /// within the collection).
13515 ///
13516 /// This call is mainly useful in situations where we can't convey a
13517 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
13518 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
13519 /// handle, which can be joined back up with a `BufferCollection` client end
13520 /// that was created via a different path. Prefer to convey a
13521 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
13522 ///
13523 /// Trusting a `buffer_collection_id` value from a source other than sysmem
13524 /// is analogous to trusting a koid value from a source other than zircon.
13525 /// Both should be avoided unless really necessary, and both require
13526 /// caution. In some situations it may be reasonable to refer to a
13527 /// pre-established `BufferCollection` by `buffer_collection_id` via a
13528 /// protocol for efficiency reasons, but an incoming value purporting to be
13529 /// a `buffer_collection_id` is not sufficient alone to justify granting the
13530 /// sender of the `buffer_collection_id` any capability. The sender must
13531 /// first prove to a receiver that the sender has/had a VMO or has/had a
13532 /// `BufferCollectionToken` to the same collection by sending a handle that
13533 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
13534 /// `buffer_collection_id` value. The receiver should take care to avoid
13535 /// assuming that a sender had a `BufferCollectionToken` in cases where the
13536 /// sender has only proven that the sender had a VMO.
13537 ///
13538 /// - response `buffer_collection_id` This ID is unique per buffer
13539 /// collection per boot. Each buffer is uniquely identified by the
13540 /// `buffer_collection_id` and `buffer_index` together.
13541 pub fn r#get_buffer_collection_id(
13542 &self,
13543 ) -> fidl::client::QueryResponseFut<
13544 NodeGetBufferCollectionIdResponse,
13545 fidl::encoding::DefaultFuchsiaResourceDialect,
13546 > {
13547 NodeProxyInterface::r#get_buffer_collection_id(self)
13548 }
13549
13550 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
13551 /// created after this message to weak, which means that a client's `Node`
13552 /// client end (or a child created after this message) is not alone
13553 /// sufficient to keep allocated VMOs alive.
13554 ///
13555 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
13556 /// `close_weak_asap`.
13557 ///
13558 /// This message is only permitted before the `Node` becomes ready for
13559 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
13560 /// * `BufferCollectionToken`: any time
13561 /// * `BufferCollection`: before `SetConstraints`
13562 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
13563 ///
13564 /// Currently, no conversion from strong `Node` to weak `Node` after ready
13565 /// for allocation is provided, but a client can simulate that by creating
13566 /// an additional `Node` before allocation and setting that additional
13567 /// `Node` to weak, and then potentially at some point later sending
13568 /// `Release` and closing the client end of the client's strong `Node`, but
13569 /// keeping the client's weak `Node`.
13570 ///
13571 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
13572 /// collection failure (all `Node` client end(s) will see
13573 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
13574 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
13575 /// this situation until all `Node`(s) are ready for allocation. For initial
13576 /// allocation to succeed, at least one strong `Node` is required to exist
13577 /// at allocation time, but after that client receives VMO handles, that
13578 /// client can `BufferCollection.Release` and close the client end without
13579 /// causing this type of failure.
13580 ///
13581 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
13582 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
13583 /// separately as appropriate.
13584 pub fn r#set_weak(&self) -> Result<(), fidl::Error> {
13585 NodeProxyInterface::r#set_weak(self)
13586 }
13587
13588 /// This indicates to sysmem that the client is prepared to pay attention to
13589 /// `close_weak_asap`.
13590 ///
13591 /// If sent, this message must be before
13592 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
13593 ///
13594 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
13595 /// send this message before `WaitForAllBuffersAllocated`, or a parent
13596 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
13597 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
13598 /// trigger buffer collection failure.
13599 ///
13600 /// This message is necessary because weak sysmem VMOs have not always been
13601 /// a thing, so older clients are not aware of the need to pay attention to
13602 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
13603 /// sysmem weak VMO handles asap. By having this message and requiring
13604 /// participants to indicate their acceptance of this aspect of the overall
13605 /// protocol, we avoid situations where an older client is delivered a weak
13606 /// VMO without any way for sysmem to get that VMO to close quickly later
13607 /// (and on a per-buffer basis).
13608 ///
13609 /// A participant that doesn't handle `close_weak_asap` and also doesn't
13610 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
13611 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
13612 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
13613 /// same participant has a child/delegate which does retrieve VMOs, that
13614 /// child/delegate will need to send `SetWeakOk` before
13615 /// `WaitForAllBuffersAllocated`.
13616 ///
13617 /// + request `for_child_nodes_also` If present and true, this means direct
13618 /// child nodes of this node created after this message plus all
13619 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
13620 /// those nodes. Any child node of this node that was created before this
13621 /// message is not included. This setting is "sticky" in the sense that a
13622 /// subsequent `SetWeakOk` without this bool set to true does not reset
13623 /// the server-side bool. If this creates a problem for a participant, a
13624 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
13625 /// tokens instead, as appropriate. A participant should only set
13626 /// `for_child_nodes_also` true if the participant can really promise to
13627 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
13628 /// weak VMO handles held by participants holding the corresponding child
13629 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
13630 /// which are using sysmem(1) can be weak, despite the clients of those
13631 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
13632 /// direct way to find out about `close_weak_asap`. This only applies to
13633 /// descendents of this `Node` which are using sysmem(1), not to this
13634 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
13635 /// token, which will fail allocation unless an ancestor of this `Node`
13636 /// specified `for_child_nodes_also` true.
13637 pub fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
13638 NodeProxyInterface::r#set_weak_ok(self, payload)
13639 }
13640
13641 /// The server_end will be closed after this `Node` and any child nodes have
13642 /// have released their buffer counts, making those counts available for
13643 /// reservation by a different `Node` via
13644 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
13645 ///
13646 /// The `Node` buffer counts may not be released until the entire tree of
13647 /// `Node`(s) is closed or failed, because
13648 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
13649 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
13650 /// `Node` buffer counts remain reserved until the orphaned node is later
13651 /// cleaned up.
13652 ///
13653 /// If the `Node` exceeds a fairly large number of attached eventpair server
13654 /// ends, a log message will indicate this and the `Node` (and the
13655 /// appropriate) sub-tree will fail.
13656 ///
13657 /// The `server_end` will remain open when
13658 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
13659 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
13660 /// [`fuchsia.sysmem2/BufferCollection`].
13661 ///
13662 /// This message can also be used with a
13663 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
13664 pub fn r#attach_node_tracking(
13665 &self,
13666 mut payload: NodeAttachNodeTrackingRequest,
13667 ) -> Result<(), fidl::Error> {
13668 NodeProxyInterface::r#attach_node_tracking(self, payload)
13669 }
13670}
13671
13672impl NodeProxyInterface for NodeProxy {
13673 type SyncResponseFut =
13674 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
13675 fn r#sync(&self) -> Self::SyncResponseFut {
13676 fn _decode(
13677 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
13678 ) -> Result<(), fidl::Error> {
13679 let _response = fidl::client::decode_transaction_body::<
13680 fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>,
13681 fidl::encoding::DefaultFuchsiaResourceDialect,
13682 0x11ac2555cf575b54,
13683 >(_buf?)?
13684 .into_result::<NodeMarker>("sync")?;
13685 Ok(_response)
13686 }
13687 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
13688 (),
13689 0x11ac2555cf575b54,
13690 fidl::encoding::DynamicFlags::FLEXIBLE,
13691 _decode,
13692 )
13693 }
13694
13695 fn r#release(&self) -> Result<(), fidl::Error> {
13696 self.client.send::<fidl::encoding::EmptyPayload>(
13697 (),
13698 0x6a5cae7d6d6e04c6,
13699 fidl::encoding::DynamicFlags::FLEXIBLE,
13700 )
13701 }
13702
13703 fn r#set_name(&self, mut payload: &NodeSetNameRequest) -> Result<(), fidl::Error> {
13704 self.client.send::<NodeSetNameRequest>(
13705 payload,
13706 0xb41f1624f48c1e9,
13707 fidl::encoding::DynamicFlags::FLEXIBLE,
13708 )
13709 }
13710
13711 fn r#set_debug_client_info(
13712 &self,
13713 mut payload: &NodeSetDebugClientInfoRequest,
13714 ) -> Result<(), fidl::Error> {
13715 self.client.send::<NodeSetDebugClientInfoRequest>(
13716 payload,
13717 0x5cde8914608d99b1,
13718 fidl::encoding::DynamicFlags::FLEXIBLE,
13719 )
13720 }
13721
13722 fn r#set_debug_timeout_log_deadline(
13723 &self,
13724 mut payload: &NodeSetDebugTimeoutLogDeadlineRequest,
13725 ) -> Result<(), fidl::Error> {
13726 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
13727 payload,
13728 0x716b0af13d5c0806,
13729 fidl::encoding::DynamicFlags::FLEXIBLE,
13730 )
13731 }
13732
13733 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
13734 self.client.send::<fidl::encoding::EmptyPayload>(
13735 (),
13736 0x5209c77415b4dfad,
13737 fidl::encoding::DynamicFlags::FLEXIBLE,
13738 )
13739 }
13740
13741 type GetNodeRefResponseFut = fidl::client::QueryResponseFut<
13742 NodeGetNodeRefResponse,
13743 fidl::encoding::DefaultFuchsiaResourceDialect,
13744 >;
13745 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
13746 fn _decode(
13747 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
13748 ) -> Result<NodeGetNodeRefResponse, fidl::Error> {
13749 let _response = fidl::client::decode_transaction_body::<
13750 fidl::encoding::FlexibleType<NodeGetNodeRefResponse>,
13751 fidl::encoding::DefaultFuchsiaResourceDialect,
13752 0x5b3d0e51614df053,
13753 >(_buf?)?
13754 .into_result::<NodeMarker>("get_node_ref")?;
13755 Ok(_response)
13756 }
13757 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
13758 (),
13759 0x5b3d0e51614df053,
13760 fidl::encoding::DynamicFlags::FLEXIBLE,
13761 _decode,
13762 )
13763 }
13764
13765 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
13766 NodeIsAlternateForResult,
13767 fidl::encoding::DefaultFuchsiaResourceDialect,
13768 >;
13769 fn r#is_alternate_for(
13770 &self,
13771 mut payload: NodeIsAlternateForRequest,
13772 ) -> Self::IsAlternateForResponseFut {
13773 fn _decode(
13774 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
13775 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
13776 let _response = fidl::client::decode_transaction_body::<
13777 fidl::encoding::FlexibleResultType<NodeIsAlternateForResponse, Error>,
13778 fidl::encoding::DefaultFuchsiaResourceDialect,
13779 0x3a58e00157e0825,
13780 >(_buf?)?
13781 .into_result::<NodeMarker>("is_alternate_for")?;
13782 Ok(_response.map(|x| x))
13783 }
13784 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
13785 &mut payload,
13786 0x3a58e00157e0825,
13787 fidl::encoding::DynamicFlags::FLEXIBLE,
13788 _decode,
13789 )
13790 }
13791
13792 type GetBufferCollectionIdResponseFut = fidl::client::QueryResponseFut<
13793 NodeGetBufferCollectionIdResponse,
13794 fidl::encoding::DefaultFuchsiaResourceDialect,
13795 >;
13796 fn r#get_buffer_collection_id(&self) -> Self::GetBufferCollectionIdResponseFut {
13797 fn _decode(
13798 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
13799 ) -> Result<NodeGetBufferCollectionIdResponse, fidl::Error> {
13800 let _response = fidl::client::decode_transaction_body::<
13801 fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>,
13802 fidl::encoding::DefaultFuchsiaResourceDialect,
13803 0x77d19a494b78ba8c,
13804 >(_buf?)?
13805 .into_result::<NodeMarker>("get_buffer_collection_id")?;
13806 Ok(_response)
13807 }
13808 self.client.send_query_and_decode::<
13809 fidl::encoding::EmptyPayload,
13810 NodeGetBufferCollectionIdResponse,
13811 >(
13812 (),
13813 0x77d19a494b78ba8c,
13814 fidl::encoding::DynamicFlags::FLEXIBLE,
13815 _decode,
13816 )
13817 }
13818
13819 fn r#set_weak(&self) -> Result<(), fidl::Error> {
13820 self.client.send::<fidl::encoding::EmptyPayload>(
13821 (),
13822 0x22dd3ea514eeffe1,
13823 fidl::encoding::DynamicFlags::FLEXIBLE,
13824 )
13825 }
13826
13827 fn r#set_weak_ok(&self, mut payload: NodeSetWeakOkRequest) -> Result<(), fidl::Error> {
13828 self.client.send::<NodeSetWeakOkRequest>(
13829 &mut payload,
13830 0x38a44fc4d7724be9,
13831 fidl::encoding::DynamicFlags::FLEXIBLE,
13832 )
13833 }
13834
13835 fn r#attach_node_tracking(
13836 &self,
13837 mut payload: NodeAttachNodeTrackingRequest,
13838 ) -> Result<(), fidl::Error> {
13839 self.client.send::<NodeAttachNodeTrackingRequest>(
13840 &mut payload,
13841 0x3f22f2a293d3cdac,
13842 fidl::encoding::DynamicFlags::FLEXIBLE,
13843 )
13844 }
13845}
13846
13847pub struct NodeEventStream {
13848 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
13849}
13850
13851impl std::marker::Unpin for NodeEventStream {}
13852
13853impl futures::stream::FusedStream for NodeEventStream {
13854 fn is_terminated(&self) -> bool {
13855 self.event_receiver.is_terminated()
13856 }
13857}
13858
13859impl futures::Stream for NodeEventStream {
13860 type Item = Result<NodeEvent, fidl::Error>;
13861
13862 fn poll_next(
13863 mut self: std::pin::Pin<&mut Self>,
13864 cx: &mut std::task::Context<'_>,
13865 ) -> std::task::Poll<Option<Self::Item>> {
13866 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
13867 &mut self.event_receiver,
13868 cx
13869 )?) {
13870 Some(buf) => std::task::Poll::Ready(Some(NodeEvent::decode(buf))),
13871 None => std::task::Poll::Ready(None),
13872 }
13873 }
13874}
13875
13876#[derive(Debug)]
13877pub enum NodeEvent {
13878 #[non_exhaustive]
13879 _UnknownEvent {
13880 /// Ordinal of the event that was sent.
13881 ordinal: u64,
13882 },
13883}
13884
13885impl NodeEvent {
13886 /// Decodes a message buffer as a [`NodeEvent`].
13887 fn decode(
13888 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
13889 ) -> Result<NodeEvent, fidl::Error> {
13890 let (bytes, _handles) = buf.split_mut();
13891 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
13892 debug_assert_eq!(tx_header.tx_id, 0);
13893 match tx_header.ordinal {
13894 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
13895 Ok(NodeEvent::_UnknownEvent { ordinal: tx_header.ordinal })
13896 }
13897 _ => Err(fidl::Error::UnknownOrdinal {
13898 ordinal: tx_header.ordinal,
13899 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
13900 }),
13901 }
13902 }
13903}
13904
13905/// A Stream of incoming requests for fuchsia.sysmem2/Node.
13906pub struct NodeRequestStream {
13907 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
13908 is_terminated: bool,
13909}
13910
13911impl std::marker::Unpin for NodeRequestStream {}
13912
13913impl futures::stream::FusedStream for NodeRequestStream {
13914 fn is_terminated(&self) -> bool {
13915 self.is_terminated
13916 }
13917}
13918
13919impl fidl::endpoints::RequestStream for NodeRequestStream {
13920 type Protocol = NodeMarker;
13921 type ControlHandle = NodeControlHandle;
13922
13923 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
13924 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
13925 }
13926
13927 fn control_handle(&self) -> Self::ControlHandle {
13928 NodeControlHandle { inner: self.inner.clone() }
13929 }
13930
13931 fn into_inner(
13932 self,
13933 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
13934 {
13935 (self.inner, self.is_terminated)
13936 }
13937
13938 fn from_inner(
13939 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
13940 is_terminated: bool,
13941 ) -> Self {
13942 Self { inner, is_terminated }
13943 }
13944}
13945
13946impl futures::Stream for NodeRequestStream {
13947 type Item = Result<NodeRequest, fidl::Error>;
13948
13949 fn poll_next(
13950 mut self: std::pin::Pin<&mut Self>,
13951 cx: &mut std::task::Context<'_>,
13952 ) -> std::task::Poll<Option<Self::Item>> {
13953 let this = &mut *self;
13954 if this.inner.check_shutdown(cx) {
13955 this.is_terminated = true;
13956 return std::task::Poll::Ready(None);
13957 }
13958 if this.is_terminated {
13959 panic!("polled NodeRequestStream after completion");
13960 }
13961 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
13962 |bytes, handles| {
13963 match this.inner.channel().read_etc(cx, bytes, handles) {
13964 std::task::Poll::Ready(Ok(())) => {}
13965 std::task::Poll::Pending => return std::task::Poll::Pending,
13966 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
13967 this.is_terminated = true;
13968 return std::task::Poll::Ready(None);
13969 }
13970 std::task::Poll::Ready(Err(e)) => {
13971 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
13972 e.into(),
13973 ))));
13974 }
13975 }
13976
13977 // A message has been received from the channel
13978 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
13979
13980 std::task::Poll::Ready(Some(match header.ordinal {
13981 0x11ac2555cf575b54 => {
13982 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
13983 let mut req = fidl::new_empty!(
13984 fidl::encoding::EmptyPayload,
13985 fidl::encoding::DefaultFuchsiaResourceDialect
13986 );
13987 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
13988 let control_handle = NodeControlHandle { inner: this.inner.clone() };
13989 Ok(NodeRequest::Sync {
13990 responder: NodeSyncResponder {
13991 control_handle: std::mem::ManuallyDrop::new(control_handle),
13992 tx_id: header.tx_id,
13993 },
13994 })
13995 }
13996 0x6a5cae7d6d6e04c6 => {
13997 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
13998 let mut req = fidl::new_empty!(
13999 fidl::encoding::EmptyPayload,
14000 fidl::encoding::DefaultFuchsiaResourceDialect
14001 );
14002 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14003 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14004 Ok(NodeRequest::Release { control_handle })
14005 }
14006 0xb41f1624f48c1e9 => {
14007 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14008 let mut req = fidl::new_empty!(
14009 NodeSetNameRequest,
14010 fidl::encoding::DefaultFuchsiaResourceDialect
14011 );
14012 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
14013 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14014 Ok(NodeRequest::SetName { payload: req, control_handle })
14015 }
14016 0x5cde8914608d99b1 => {
14017 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14018 let mut req = fidl::new_empty!(
14019 NodeSetDebugClientInfoRequest,
14020 fidl::encoding::DefaultFuchsiaResourceDialect
14021 );
14022 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
14023 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14024 Ok(NodeRequest::SetDebugClientInfo { payload: req, control_handle })
14025 }
14026 0x716b0af13d5c0806 => {
14027 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14028 let mut req = fidl::new_empty!(
14029 NodeSetDebugTimeoutLogDeadlineRequest,
14030 fidl::encoding::DefaultFuchsiaResourceDialect
14031 );
14032 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
14033 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14034 Ok(NodeRequest::SetDebugTimeoutLogDeadline { payload: req, control_handle })
14035 }
14036 0x5209c77415b4dfad => {
14037 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14038 let mut req = fidl::new_empty!(
14039 fidl::encoding::EmptyPayload,
14040 fidl::encoding::DefaultFuchsiaResourceDialect
14041 );
14042 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14043 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14044 Ok(NodeRequest::SetVerboseLogging { control_handle })
14045 }
14046 0x5b3d0e51614df053 => {
14047 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
14048 let mut req = fidl::new_empty!(
14049 fidl::encoding::EmptyPayload,
14050 fidl::encoding::DefaultFuchsiaResourceDialect
14051 );
14052 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14053 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14054 Ok(NodeRequest::GetNodeRef {
14055 responder: NodeGetNodeRefResponder {
14056 control_handle: std::mem::ManuallyDrop::new(control_handle),
14057 tx_id: header.tx_id,
14058 },
14059 })
14060 }
14061 0x3a58e00157e0825 => {
14062 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
14063 let mut req = fidl::new_empty!(
14064 NodeIsAlternateForRequest,
14065 fidl::encoding::DefaultFuchsiaResourceDialect
14066 );
14067 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
14068 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14069 Ok(NodeRequest::IsAlternateFor {
14070 payload: req,
14071 responder: NodeIsAlternateForResponder {
14072 control_handle: std::mem::ManuallyDrop::new(control_handle),
14073 tx_id: header.tx_id,
14074 },
14075 })
14076 }
14077 0x77d19a494b78ba8c => {
14078 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
14079 let mut req = fidl::new_empty!(
14080 fidl::encoding::EmptyPayload,
14081 fidl::encoding::DefaultFuchsiaResourceDialect
14082 );
14083 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14084 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14085 Ok(NodeRequest::GetBufferCollectionId {
14086 responder: NodeGetBufferCollectionIdResponder {
14087 control_handle: std::mem::ManuallyDrop::new(control_handle),
14088 tx_id: header.tx_id,
14089 },
14090 })
14091 }
14092 0x22dd3ea514eeffe1 => {
14093 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14094 let mut req = fidl::new_empty!(
14095 fidl::encoding::EmptyPayload,
14096 fidl::encoding::DefaultFuchsiaResourceDialect
14097 );
14098 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
14099 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14100 Ok(NodeRequest::SetWeak { control_handle })
14101 }
14102 0x38a44fc4d7724be9 => {
14103 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14104 let mut req = fidl::new_empty!(
14105 NodeSetWeakOkRequest,
14106 fidl::encoding::DefaultFuchsiaResourceDialect
14107 );
14108 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetWeakOkRequest>(&header, _body_bytes, handles, &mut req)?;
14109 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14110 Ok(NodeRequest::SetWeakOk { payload: req, control_handle })
14111 }
14112 0x3f22f2a293d3cdac => {
14113 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
14114 let mut req = fidl::new_empty!(
14115 NodeAttachNodeTrackingRequest,
14116 fidl::encoding::DefaultFuchsiaResourceDialect
14117 );
14118 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeAttachNodeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
14119 let control_handle = NodeControlHandle { inner: this.inner.clone() };
14120 Ok(NodeRequest::AttachNodeTracking { payload: req, control_handle })
14121 }
14122 _ if header.tx_id == 0
14123 && header
14124 .dynamic_flags()
14125 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
14126 {
14127 Ok(NodeRequest::_UnknownMethod {
14128 ordinal: header.ordinal,
14129 control_handle: NodeControlHandle { inner: this.inner.clone() },
14130 method_type: fidl::MethodType::OneWay,
14131 })
14132 }
14133 _ if header
14134 .dynamic_flags()
14135 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
14136 {
14137 this.inner.send_framework_err(
14138 fidl::encoding::FrameworkErr::UnknownMethod,
14139 header.tx_id,
14140 header.ordinal,
14141 header.dynamic_flags(),
14142 (bytes, handles),
14143 )?;
14144 Ok(NodeRequest::_UnknownMethod {
14145 ordinal: header.ordinal,
14146 control_handle: NodeControlHandle { inner: this.inner.clone() },
14147 method_type: fidl::MethodType::TwoWay,
14148 })
14149 }
14150 _ => Err(fidl::Error::UnknownOrdinal {
14151 ordinal: header.ordinal,
14152 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
14153 }),
14154 }))
14155 },
14156 )
14157 }
14158}
14159
14160/// This protocol is the parent protocol for all nodes in the tree established
14161/// by [`fuchsia.sysmem2/BufferCollectionToken`] creation and
14162/// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] creation, including
14163/// [`fuchsia.sysmem2/BufferCollectionToken`](s) which have since been converted
14164/// to a [`fuchsia.sysmem2/BufferCollection`] channel.
14165///
14166/// Epitaphs are not used in this protocol.
14167#[derive(Debug)]
14168pub enum NodeRequest {
14169 /// Ensure that previous messages have been received server side. This is
14170 /// particularly useful after previous messages that created new tokens,
14171 /// because a token must be known to the sysmem server before sending the
14172 /// token to another participant.
14173 ///
14174 /// Calling [`fuchsia.sysmem2/BufferCollectionToken.Sync`] on a token that
14175 /// isn't/wasn't a valid token risks the `Sync` stalling forever. See
14176 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] for one way
14177 /// to mitigate the possibility of a hostile/fake
14178 /// [`fuchsia.sysmem2/BufferCollectionToken`] at the cost of one round trip.
14179 /// Another way is to pass the token to
14180 /// [`fuchsia.sysmem2/Allocator/BindSharedCollection`], which also validates
14181 /// the token as part of exchanging it for a
14182 /// [`fuchsia.sysmem2/BufferCollection`] channel, and
14183 /// [`fuchsia.sysmem2/BufferCollection.Sync`] can then be used without risk
14184 /// of stalling.
14185 ///
14186 /// After creating one or more [`fuchsia.sysmem2/BufferCollectionToken`](s)
14187 /// and then starting and completing a `Sync`, it's then safe to send the
14188 /// `BufferCollectionToken` client ends to other participants knowing the
14189 /// server will recognize the tokens when they're sent by the other
14190 /// participants to sysmem in a
14191 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] message. This is an
14192 /// efficient way to create tokens while avoiding unnecessary round trips.
14193 ///
14194 /// Other options include waiting for each
14195 /// [`fuchsia.sysmem2/BufferCollectionToken.Duplicate`] to complete
14196 /// individually (using separate call to `Sync` after each), or calling
14197 /// [`fuchsia.sysmem2/BufferCollection.Sync`] after a token has been
14198 /// converted to a `BufferCollection` via
14199 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`], or using
14200 /// [`fuchsia.sysmem2/BufferCollectionToken.DuplicateSync`] which includes
14201 /// the sync step and can create multiple tokens at once.
14202 Sync { responder: NodeSyncResponder },
14203 /// ###### On a [`fuchsia.sysmem2/BufferCollectionToken`] channel:
14204 ///
14205 /// Normally a participant will convert a `BufferCollectionToken` into a
14206 /// [`fuchsia.sysmem2/BufferCollection`], but a participant can instead send
14207 /// `Release` via the token (and then close the channel immediately or
14208 /// shortly later in response to server closing the server end), which
14209 /// avoids causing buffer collection failure. Without a prior `Release`,
14210 /// closing the `BufferCollectionToken` client end will cause buffer
14211 /// collection failure.
14212 ///
14213 /// ###### On a [`fuchsia.sysmem2/BufferCollection`] channel:
14214 ///
14215 /// By default the server handles unexpected closure of a
14216 /// [`fuchsia.sysmem2/BufferCollection`] client end (without `Release`
14217 /// first) by failing the buffer collection. Partly this is to expedite
14218 /// closing VMO handles to reclaim memory when any participant fails. If a
14219 /// participant would like to cleanly close a `BufferCollection` without
14220 /// causing buffer collection failure, the participant can send `Release`
14221 /// before closing the `BufferCollection` client end. The `Release` can
14222 /// occur before or after `SetConstraints`. If before `SetConstraints`, the
14223 /// buffer collection won't require constraints from this node in order to
14224 /// allocate. If after `SetConstraints`, the constraints are retained and
14225 /// aggregated, despite the lack of `BufferCollection` connection at the
14226 /// time of constraints aggregation.
14227 ///
14228 /// ###### On a [`fuchsia.sysmem2/BufferCollectionTokenGroup`] channel:
14229 ///
14230 /// By default, unexpected closure of a `BufferCollectionTokenGroup` client
14231 /// end (without `Release` first) will trigger failure of the buffer
14232 /// collection. To close a `BufferCollectionTokenGroup` channel without
14233 /// failing the buffer collection, ensure that AllChildrenPresent() has been
14234 /// sent, and send `Release` before closing the `BufferCollectionTokenGroup`
14235 /// client end.
14236 ///
14237 /// If `Release` occurs before
14238 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the
14239 /// buffer collection will fail (triggered by reception of `Release` without
14240 /// prior `AllChildrenPresent`). This is intentionally not analogous to how
14241 /// [`fuchsia.sysmem2/BufferCollection.Release`] without
14242 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] first doesn't cause
14243 /// buffer collection failure. For a `BufferCollectionTokenGroup`, clean
14244 /// close requires `AllChildrenPresent` (if not already sent), then
14245 /// `Release`, then close client end.
14246 ///
14247 /// If `Release` occurs after `AllChildrenPresent`, the children and all
14248 /// their constraints remain intact (just as they would if the
14249 /// `BufferCollectionTokenGroup` channel had remained open), and the client
14250 /// end close doesn't trigger buffer collection failure.
14251 ///
14252 /// ###### On all [`fuchsia.sysmem2/Node`] channels (any of the above):
14253 ///
14254 /// For brevity, the per-channel-protocol paragraphs above ignore the
14255 /// separate failure domain created by
14256 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`] or
14257 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`]. When a client end
14258 /// unexpectedly closes (without `Release` first) and that client end is
14259 /// under a failure domain, instead of failing the whole buffer collection,
14260 /// the failure domain is failed, but the buffer collection itself is
14261 /// isolated from failure of the failure domain. Such failure domains can be
14262 /// nested, in which case only the inner-most failure domain in which the
14263 /// `Node` resides fails.
14264 Release { control_handle: NodeControlHandle },
14265 /// Set a name for VMOs in this buffer collection.
14266 ///
14267 /// If the name doesn't fit in ZX_MAX_NAME_LEN, the name of the vmo itself
14268 /// will be truncated to fit. The name of the vmo will be suffixed with the
14269 /// buffer index within the collection (if the suffix fits within
14270 /// ZX_MAX_NAME_LEN). The name specified here (without truncation) will be
14271 /// listed in the inspect data.
14272 ///
14273 /// The name only affects VMOs allocated after the name is set; this call
14274 /// does not rename existing VMOs. If multiple clients set different names
14275 /// then the larger priority value will win. Setting a new name with the
14276 /// same priority as a prior name doesn't change the name.
14277 ///
14278 /// All table fields are currently required.
14279 ///
14280 /// + request `priority` The name is only set if this is the first `SetName`
14281 /// or if `priority` is greater than any previous `priority` value in
14282 /// prior `SetName` calls across all `Node`(s) of this buffer collection.
14283 /// + request `name` The name for VMOs created under this buffer collection.
14284 SetName { payload: NodeSetNameRequest, control_handle: NodeControlHandle },
14285 /// Set information about the current client that can be used by sysmem to
14286 /// help diagnose leaking memory and allocation stalls waiting for a
14287 /// participant to send [`fuchsia.sysmem2/BufferCollection.SetConstraints`].
14288 ///
14289 /// This sets the debug client info on this [`fuchsia.sysmem2/Node`] and all
14290 /// `Node`(s) derived from this `Node`, unless overriden by
14291 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] or a later
14292 /// [`fuchsia.sysmem2/Node.SetDebugClientInfo`].
14293 ///
14294 /// Sending [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`] once per
14295 /// `Allocator` is the most efficient way to ensure that all
14296 /// [`fuchsia.sysmem2/Node`](s) will have at least some debug client info
14297 /// set, and is also more efficient than separately sending the same debug
14298 /// client info via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] for each
14299 /// created [`fuchsia.sysmem2/Node`].
14300 ///
14301 /// Also used when verbose logging is enabled (see `SetVerboseLogging`) to
14302 /// indicate which client is closing their channel first, leading to subtree
14303 /// failure (which can be normal if the purpose of the subtree is over, but
14304 /// if happening earlier than expected, the client-channel-specific name can
14305 /// help diagnose where the failure is first coming from, from sysmem's
14306 /// point of view).
14307 ///
14308 /// All table fields are currently required.
14309 ///
14310 /// + request `name` This can be an arbitrary string, but the current
14311 /// process name (see `fsl::GetCurrentProcessName`) is a good default.
14312 /// + request `id` This can be an arbitrary id, but the current process ID
14313 /// (see `fsl::GetCurrentProcessKoid`) is a good default.
14314 SetDebugClientInfo { payload: NodeSetDebugClientInfoRequest, control_handle: NodeControlHandle },
14315 /// Sysmem logs a warning if sysmem hasn't seen
14316 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from all clients
14317 /// within 5 seconds after creation of a new collection.
14318 ///
14319 /// Clients can call this method to change when the log is printed. If
14320 /// multiple client set the deadline, it's unspecified which deadline will
14321 /// take effect.
14322 ///
14323 /// In most cases the default works well.
14324 ///
14325 /// All table fields are currently required.
14326 ///
14327 /// + request `deadline` The time at which sysmem will start trying to log
14328 /// the warning, unless all constraints are with sysmem by then.
14329 SetDebugTimeoutLogDeadline {
14330 payload: NodeSetDebugTimeoutLogDeadlineRequest,
14331 control_handle: NodeControlHandle,
14332 },
14333 /// This enables verbose logging for the buffer collection.
14334 ///
14335 /// Verbose logging includes constraints set via
14336 /// [`fuchsia.sysmem2/BufferCollection.SetConstraints`] from each client
14337 /// along with info set via [`fuchsia.sysmem2/Node.SetDebugClientInfo`] (or
14338 /// [`fuchsia.sysmem2/Allocator.SetDebugClientInfo`]) and the structure of
14339 /// the tree of `Node`(s).
14340 ///
14341 /// Normally sysmem prints only a single line complaint when aggregation
14342 /// fails, with just the specific detailed reason that aggregation failed,
14343 /// with little surrounding context. While this is often enough to diagnose
14344 /// a problem if only a small change was made and everything was working
14345 /// before the small change, it's often not particularly helpful for getting
14346 /// a new buffer collection to work for the first time. Especially with
14347 /// more complex trees of nodes, involving things like
14348 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`],
14349 /// [`fuchsia.sysmem2/BufferCollectionToken.SetDispensable`],
14350 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`] nodes, and associated
14351 /// subtrees of nodes, verbose logging may help in diagnosing what the tree
14352 /// looks like and why it's failing a logical allocation, or why a tree or
14353 /// subtree is failing sooner than expected.
14354 ///
14355 /// The intent of the extra logging is to be acceptable from a performance
14356 /// point of view, under the assumption that verbose logging is only enabled
14357 /// on a low number of buffer collections. If we're not tracking down a bug,
14358 /// we shouldn't send this message.
14359 SetVerboseLogging { control_handle: NodeControlHandle },
14360 /// This gets a handle that can be used as a parameter to
14361 /// [`fuchsia.sysmem2/Node.IsAlternateFor`] called on any
14362 /// [`fuchsia.sysmem2/Node`]. This handle is only for use as proof that the
14363 /// client obtained this handle from this `Node`.
14364 ///
14365 /// Because this is a get not a set, no [`fuchsia.sysmem2/Node.Sync`] is
14366 /// needed between the `GetNodeRef` and the call to `IsAlternateFor`,
14367 /// despite the two calls typically being on different channels.
14368 ///
14369 /// See also [`fuchsia.sysmem2/Node.IsAlternateFor`].
14370 ///
14371 /// All table fields are currently required.
14372 ///
14373 /// - response `node_ref` This handle can be sent via `IsAlternateFor` on a
14374 /// different `Node` channel, to prove that the client obtained the handle
14375 /// from this `Node`.
14376 GetNodeRef { responder: NodeGetNodeRefResponder },
14377 /// Check whether the calling [`fuchsia.sysmem2/Node`] is in a subtree
14378 /// rooted at a different child token of a common parent
14379 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`], in relation to the
14380 /// passed-in `node_ref`.
14381 ///
14382 /// This call is for assisting with admission control de-duplication, and
14383 /// with debugging.
14384 ///
14385 /// The `node_ref` must be obtained using
14386 /// [`fuchsia.sysmem2/Node.GetNodeRef`].
14387 ///
14388 /// The `node_ref` can be a duplicated handle; it's not necessary to call
14389 /// `GetNodeRef` for every call to [`fuchsia.sysmem2/Node.IsAlternateFor`].
14390 ///
14391 /// If a calling token may not actually be a valid token at all due to a
14392 /// potentially hostile/untrusted provider of the token, call
14393 /// [`fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken`] first
14394 /// instead of potentially getting stuck indefinitely if `IsAlternateFor`
14395 /// never responds due to a calling token not being a real token (not really
14396 /// talking to sysmem). Another option is to call
14397 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] with this token first
14398 /// which also validates the token along with converting it to a
14399 /// [`fuchsia.sysmem2/BufferCollection`], then call `IsAlternateFor`.
14400 ///
14401 /// All table fields are currently required.
14402 ///
14403 /// - response `is_alternate`
14404 /// - true: The first parent node in common between the calling node and
14405 /// the `node_ref` `Node` is a `BufferCollectionTokenGroup`. This means
14406 /// that the calling `Node` and the `node_ref` `Node` will not have both
14407 /// their constraints apply - rather sysmem will choose one or the other
14408 /// of the constraints - never both. This is because only one child of
14409 /// a `BufferCollectionTokenGroup` is selected during logical
14410 /// allocation, with only that one child's subtree contributing to
14411 /// constraints aggregation.
14412 /// - false: The first parent node in common between the calling `Node`
14413 /// and the `node_ref` `Node` is not a `BufferCollectionTokenGroup`.
14414 /// Currently, this means the first parent node in common is a
14415 /// `BufferCollectionToken` or `BufferCollection` (regardless of not
14416 /// `Release`ed). This means that the calling `Node` and the `node_ref`
14417 /// `Node` may have both their constraints apply during constraints
14418 /// aggregation of the logical allocation, if both `Node`(s) are
14419 /// selected by any parent `BufferCollectionTokenGroup`(s) involved. In
14420 /// this case, there is no `BufferCollectionTokenGroup` that will
14421 /// directly prevent the two `Node`(s) from both being selected and
14422 /// their constraints both aggregated, but even when false, one or both
14423 /// `Node`(s) may still be eliminated from consideration if one or both
14424 /// `Node`(s) has a direct or indirect parent
14425 /// `BufferCollectionTokenGroup` which selects a child subtree other
14426 /// than the subtree containing the calling `Node` or `node_ref` `Node`.
14427 /// * error `[fuchsia.sysmem2/Error.NOT_FOUND]` The node_ref wasn't
14428 /// associated with the same buffer collection as the calling `Node`.
14429 /// Another reason for this error is if the `node_ref` is an
14430 /// [`zx.Handle.EVENT`] handle with sufficient rights, but isn't actually
14431 /// a real `node_ref` obtained from `GetNodeRef`.
14432 /// * error `[fuchsia.sysmem2/Error.PROTOCOL_DEVIATION]` The caller passed a
14433 /// `node_ref` that isn't a [`zx.Handle:EVENT`] handle , or doesn't have
14434 /// the needed rights expected on a real `node_ref`.
14435 /// * No other failing status codes are returned by this call. However,
14436 /// sysmem may add additional codes in future, so the client should have
14437 /// sensible default handling for any failing status code.
14438 IsAlternateFor { payload: NodeIsAlternateForRequest, responder: NodeIsAlternateForResponder },
14439 /// Get the buffer collection ID. This ID is also available from
14440 /// [`fuchsia.sysmem2/Allocator.GetVmoInfo`] (along with the `buffer_index`
14441 /// within the collection).
14442 ///
14443 /// This call is mainly useful in situations where we can't convey a
14444 /// [`fuchsia.sysmem2/BufferCollectionToken`] or
14445 /// [`fuchsia.sysmem2/BufferCollection`] directly, but can only convey a VMO
14446 /// handle, which can be joined back up with a `BufferCollection` client end
14447 /// that was created via a different path. Prefer to convey a
14448 /// `BufferCollectionToken` or `BufferCollection` directly when feasible.
14449 ///
14450 /// Trusting a `buffer_collection_id` value from a source other than sysmem
14451 /// is analogous to trusting a koid value from a source other than zircon.
14452 /// Both should be avoided unless really necessary, and both require
14453 /// caution. In some situations it may be reasonable to refer to a
14454 /// pre-established `BufferCollection` by `buffer_collection_id` via a
14455 /// protocol for efficiency reasons, but an incoming value purporting to be
14456 /// a `buffer_collection_id` is not sufficient alone to justify granting the
14457 /// sender of the `buffer_collection_id` any capability. The sender must
14458 /// first prove to a receiver that the sender has/had a VMO or has/had a
14459 /// `BufferCollectionToken` to the same collection by sending a handle that
14460 /// sysmem confirms is a valid sysmem handle and which sysmem maps to the
14461 /// `buffer_collection_id` value. The receiver should take care to avoid
14462 /// assuming that a sender had a `BufferCollectionToken` in cases where the
14463 /// sender has only proven that the sender had a VMO.
14464 ///
14465 /// - response `buffer_collection_id` This ID is unique per buffer
14466 /// collection per boot. Each buffer is uniquely identified by the
14467 /// `buffer_collection_id` and `buffer_index` together.
14468 GetBufferCollectionId { responder: NodeGetBufferCollectionIdResponder },
14469 /// Sets the current [`fuchsia.sysmem2/Node`] and all child `Node`(s)
14470 /// created after this message to weak, which means that a client's `Node`
14471 /// client end (or a child created after this message) is not alone
14472 /// sufficient to keep allocated VMOs alive.
14473 ///
14474 /// All VMOs obtained from weak `Node`(s) are weak sysmem VMOs. See also
14475 /// `close_weak_asap`.
14476 ///
14477 /// This message is only permitted before the `Node` becomes ready for
14478 /// allocation (else the server closes the channel with `ZX_ERR_BAD_STATE`):
14479 /// * `BufferCollectionToken`: any time
14480 /// * `BufferCollection`: before `SetConstraints`
14481 /// * `BufferCollectionTokenGroup`: before `AllChildrenPresent`
14482 ///
14483 /// Currently, no conversion from strong `Node` to weak `Node` after ready
14484 /// for allocation is provided, but a client can simulate that by creating
14485 /// an additional `Node` before allocation and setting that additional
14486 /// `Node` to weak, and then potentially at some point later sending
14487 /// `Release` and closing the client end of the client's strong `Node`, but
14488 /// keeping the client's weak `Node`.
14489 ///
14490 /// Zero strong `Node`(s) and zero strong VMO handles will result in buffer
14491 /// collection failure (all `Node` client end(s) will see
14492 /// `ZX_CHANNEL_PEER_CLOSED` and all `close_weak_asap` `client_end`(s) will
14493 /// see `ZX_EVENTPAIR_PEER_CLOSED`), but sysmem (intentionally) won't notice
14494 /// this situation until all `Node`(s) are ready for allocation. For initial
14495 /// allocation to succeed, at least one strong `Node` is required to exist
14496 /// at allocation time, but after that client receives VMO handles, that
14497 /// client can `BufferCollection.Release` and close the client end without
14498 /// causing this type of failure.
14499 ///
14500 /// This implies [`fuchsia.sysmem2/Node.SetWeakOk`] as well, but does not
14501 /// imply `SetWeakOk` with `for_children_also` true, which can be sent
14502 /// separately as appropriate.
14503 SetWeak { control_handle: NodeControlHandle },
14504 /// This indicates to sysmem that the client is prepared to pay attention to
14505 /// `close_weak_asap`.
14506 ///
14507 /// If sent, this message must be before
14508 /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`].
14509 ///
14510 /// All participants using a weak [`fuchsia.sysmem2/BufferCollection`] must
14511 /// send this message before `WaitForAllBuffersAllocated`, or a parent
14512 /// `Node` must have sent [`fuchsia.sysmem2/Node.SetWeakOk`] with
14513 /// `for_child_nodes_also` true, else the `WaitForAllBuffersAllocated` will
14514 /// trigger buffer collection failure.
14515 ///
14516 /// This message is necessary because weak sysmem VMOs have not always been
14517 /// a thing, so older clients are not aware of the need to pay attention to
14518 /// `close_weak_asap` `ZX_EVENTPAIR_PEER_CLOSED` and close all remaining
14519 /// sysmem weak VMO handles asap. By having this message and requiring
14520 /// participants to indicate their acceptance of this aspect of the overall
14521 /// protocol, we avoid situations where an older client is delivered a weak
14522 /// VMO without any way for sysmem to get that VMO to close quickly later
14523 /// (and on a per-buffer basis).
14524 ///
14525 /// A participant that doesn't handle `close_weak_asap` and also doesn't
14526 /// retrieve any VMO handles via `WaitForAllBuffersAllocated` doesn't need
14527 /// to send `SetWeakOk` (and doesn't need to have a parent `Node` send
14528 /// `SetWeakOk` with `for_child_nodes_also` true either). However, if that
14529 /// same participant has a child/delegate which does retrieve VMOs, that
14530 /// child/delegate will need to send `SetWeakOk` before
14531 /// `WaitForAllBuffersAllocated`.
14532 ///
14533 /// + request `for_child_nodes_also` If present and true, this means direct
14534 /// child nodes of this node created after this message plus all
14535 /// descendants of those nodes will behave as if `SetWeakOk` was sent on
14536 /// those nodes. Any child node of this node that was created before this
14537 /// message is not included. This setting is "sticky" in the sense that a
14538 /// subsequent `SetWeakOk` without this bool set to true does not reset
14539 /// the server-side bool. If this creates a problem for a participant, a
14540 /// workaround is to `SetWeakOk` with `for_child_nodes_also` true on child
14541 /// tokens instead, as appropriate. A participant should only set
14542 /// `for_child_nodes_also` true if the participant can really promise to
14543 /// obey `close_weak_asap` both for its own weak VMO handles, and for all
14544 /// weak VMO handles held by participants holding the corresponding child
14545 /// `Node`(s). When `for_child_nodes_also` is set, descendent `Node`(s)
14546 /// which are using sysmem(1) can be weak, despite the clients of those
14547 /// sysmem1 `Node`(s) not having any direct way to `SetWeakOk` or any
14548 /// direct way to find out about `close_weak_asap`. This only applies to
14549 /// descendents of this `Node` which are using sysmem(1), not to this
14550 /// `Node` when converted directly from a sysmem2 token to a sysmem(1)
14551 /// token, which will fail allocation unless an ancestor of this `Node`
14552 /// specified `for_child_nodes_also` true.
14553 SetWeakOk { payload: NodeSetWeakOkRequest, control_handle: NodeControlHandle },
14554 /// The server_end will be closed after this `Node` and any child nodes have
14555 /// have released their buffer counts, making those counts available for
14556 /// reservation by a different `Node` via
14557 /// [`fuchsia.sysmem2/BufferCollection.AttachToken`].
14558 ///
14559 /// The `Node` buffer counts may not be released until the entire tree of
14560 /// `Node`(s) is closed or failed, because
14561 /// [`fuchsia.sysmem2/BufferCollection.Release`] followed by channel close
14562 /// does not immediately un-reserve the `Node` buffer counts. Instead, the
14563 /// `Node` buffer counts remain reserved until the orphaned node is later
14564 /// cleaned up.
14565 ///
14566 /// If the `Node` exceeds a fairly large number of attached eventpair server
14567 /// ends, a log message will indicate this and the `Node` (and the
14568 /// appropriate) sub-tree will fail.
14569 ///
14570 /// The `server_end` will remain open when
14571 /// [`fuchsia.sysmem2/Allocator.BindSharedCollection`] converts a
14572 /// [`fuchsia.sysmem2/BufferCollectionToken`] into a
14573 /// [`fuchsia.sysmem2/BufferCollection`].
14574 ///
14575 /// This message can also be used with a
14576 /// [`fuchsia.sysmem2/BufferCollectionTokenGroup`].
14577 AttachNodeTracking { payload: NodeAttachNodeTrackingRequest, control_handle: NodeControlHandle },
14578 /// An interaction was received which does not match any known method.
14579 #[non_exhaustive]
14580 _UnknownMethod {
14581 /// Ordinal of the method that was called.
14582 ordinal: u64,
14583 control_handle: NodeControlHandle,
14584 method_type: fidl::MethodType,
14585 },
14586}
14587
14588impl NodeRequest {
14589 #[allow(irrefutable_let_patterns)]
14590 pub fn into_sync(self) -> Option<(NodeSyncResponder)> {
14591 if let NodeRequest::Sync { responder } = self { Some((responder)) } else { None }
14592 }
14593
14594 #[allow(irrefutable_let_patterns)]
14595 pub fn into_release(self) -> Option<(NodeControlHandle)> {
14596 if let NodeRequest::Release { control_handle } = self {
14597 Some((control_handle))
14598 } else {
14599 None
14600 }
14601 }
14602
14603 #[allow(irrefutable_let_patterns)]
14604 pub fn into_set_name(self) -> Option<(NodeSetNameRequest, NodeControlHandle)> {
14605 if let NodeRequest::SetName { payload, control_handle } = self {
14606 Some((payload, control_handle))
14607 } else {
14608 None
14609 }
14610 }
14611
14612 #[allow(irrefutable_let_patterns)]
14613 pub fn into_set_debug_client_info(
14614 self,
14615 ) -> Option<(NodeSetDebugClientInfoRequest, NodeControlHandle)> {
14616 if let NodeRequest::SetDebugClientInfo { payload, control_handle } = self {
14617 Some((payload, control_handle))
14618 } else {
14619 None
14620 }
14621 }
14622
14623 #[allow(irrefutable_let_patterns)]
14624 pub fn into_set_debug_timeout_log_deadline(
14625 self,
14626 ) -> Option<(NodeSetDebugTimeoutLogDeadlineRequest, NodeControlHandle)> {
14627 if let NodeRequest::SetDebugTimeoutLogDeadline { payload, control_handle } = self {
14628 Some((payload, control_handle))
14629 } else {
14630 None
14631 }
14632 }
14633
14634 #[allow(irrefutable_let_patterns)]
14635 pub fn into_set_verbose_logging(self) -> Option<(NodeControlHandle)> {
14636 if let NodeRequest::SetVerboseLogging { control_handle } = self {
14637 Some((control_handle))
14638 } else {
14639 None
14640 }
14641 }
14642
14643 #[allow(irrefutable_let_patterns)]
14644 pub fn into_get_node_ref(self) -> Option<(NodeGetNodeRefResponder)> {
14645 if let NodeRequest::GetNodeRef { responder } = self { Some((responder)) } else { None }
14646 }
14647
14648 #[allow(irrefutable_let_patterns)]
14649 pub fn into_is_alternate_for(
14650 self,
14651 ) -> Option<(NodeIsAlternateForRequest, NodeIsAlternateForResponder)> {
14652 if let NodeRequest::IsAlternateFor { payload, responder } = self {
14653 Some((payload, responder))
14654 } else {
14655 None
14656 }
14657 }
14658
14659 #[allow(irrefutable_let_patterns)]
14660 pub fn into_get_buffer_collection_id(self) -> Option<(NodeGetBufferCollectionIdResponder)> {
14661 if let NodeRequest::GetBufferCollectionId { responder } = self {
14662 Some((responder))
14663 } else {
14664 None
14665 }
14666 }
14667
14668 #[allow(irrefutable_let_patterns)]
14669 pub fn into_set_weak(self) -> Option<(NodeControlHandle)> {
14670 if let NodeRequest::SetWeak { control_handle } = self {
14671 Some((control_handle))
14672 } else {
14673 None
14674 }
14675 }
14676
14677 #[allow(irrefutable_let_patterns)]
14678 pub fn into_set_weak_ok(self) -> Option<(NodeSetWeakOkRequest, NodeControlHandle)> {
14679 if let NodeRequest::SetWeakOk { payload, control_handle } = self {
14680 Some((payload, control_handle))
14681 } else {
14682 None
14683 }
14684 }
14685
14686 #[allow(irrefutable_let_patterns)]
14687 pub fn into_attach_node_tracking(
14688 self,
14689 ) -> Option<(NodeAttachNodeTrackingRequest, NodeControlHandle)> {
14690 if let NodeRequest::AttachNodeTracking { payload, control_handle } = self {
14691 Some((payload, control_handle))
14692 } else {
14693 None
14694 }
14695 }
14696
14697 /// Name of the method defined in FIDL
14698 pub fn method_name(&self) -> &'static str {
14699 match *self {
14700 NodeRequest::Sync { .. } => "sync",
14701 NodeRequest::Release { .. } => "release",
14702 NodeRequest::SetName { .. } => "set_name",
14703 NodeRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
14704 NodeRequest::SetDebugTimeoutLogDeadline { .. } => "set_debug_timeout_log_deadline",
14705 NodeRequest::SetVerboseLogging { .. } => "set_verbose_logging",
14706 NodeRequest::GetNodeRef { .. } => "get_node_ref",
14707 NodeRequest::IsAlternateFor { .. } => "is_alternate_for",
14708 NodeRequest::GetBufferCollectionId { .. } => "get_buffer_collection_id",
14709 NodeRequest::SetWeak { .. } => "set_weak",
14710 NodeRequest::SetWeakOk { .. } => "set_weak_ok",
14711 NodeRequest::AttachNodeTracking { .. } => "attach_node_tracking",
14712 NodeRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
14713 "unknown one-way method"
14714 }
14715 NodeRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
14716 "unknown two-way method"
14717 }
14718 }
14719 }
14720}
14721
14722#[derive(Debug, Clone)]
14723pub struct NodeControlHandle {
14724 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
14725}
14726
14727impl fidl::endpoints::ControlHandle for NodeControlHandle {
14728 fn shutdown(&self) {
14729 self.inner.shutdown()
14730 }
14731
14732 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
14733 self.inner.shutdown_with_epitaph(status)
14734 }
14735
14736 fn is_closed(&self) -> bool {
14737 self.inner.channel().is_closed()
14738 }
14739 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
14740 self.inner.channel().on_closed()
14741 }
14742
14743 #[cfg(target_os = "fuchsia")]
14744 fn signal_peer(
14745 &self,
14746 clear_mask: zx::Signals,
14747 set_mask: zx::Signals,
14748 ) -> Result<(), zx_status::Status> {
14749 use fidl::Peered;
14750 self.inner.channel().signal_peer(clear_mask, set_mask)
14751 }
14752}
14753
14754impl NodeControlHandle {}
14755
14756#[must_use = "FIDL methods require a response to be sent"]
14757#[derive(Debug)]
14758pub struct NodeSyncResponder {
14759 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
14760 tx_id: u32,
14761}
14762
14763/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
14764/// if the responder is dropped without sending a response, so that the client
14765/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
14766impl std::ops::Drop for NodeSyncResponder {
14767 fn drop(&mut self) {
14768 self.control_handle.shutdown();
14769 // Safety: drops once, never accessed again
14770 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14771 }
14772}
14773
14774impl fidl::endpoints::Responder for NodeSyncResponder {
14775 type ControlHandle = NodeControlHandle;
14776
14777 fn control_handle(&self) -> &NodeControlHandle {
14778 &self.control_handle
14779 }
14780
14781 fn drop_without_shutdown(mut self) {
14782 // Safety: drops once, never accessed again due to mem::forget
14783 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14784 // Prevent Drop from running (which would shut down the channel)
14785 std::mem::forget(self);
14786 }
14787}
14788
14789impl NodeSyncResponder {
14790 /// Sends a response to the FIDL transaction.
14791 ///
14792 /// Sets the channel to shutdown if an error occurs.
14793 pub fn send(self) -> Result<(), fidl::Error> {
14794 let _result = self.send_raw();
14795 if _result.is_err() {
14796 self.control_handle.shutdown();
14797 }
14798 self.drop_without_shutdown();
14799 _result
14800 }
14801
14802 /// Similar to "send" but does not shutdown the channel if an error occurs.
14803 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
14804 let _result = self.send_raw();
14805 self.drop_without_shutdown();
14806 _result
14807 }
14808
14809 fn send_raw(&self) -> Result<(), fidl::Error> {
14810 self.control_handle.inner.send::<fidl::encoding::FlexibleType<fidl::encoding::EmptyStruct>>(
14811 fidl::encoding::Flexible::new(()),
14812 self.tx_id,
14813 0x11ac2555cf575b54,
14814 fidl::encoding::DynamicFlags::FLEXIBLE,
14815 )
14816 }
14817}
14818
14819#[must_use = "FIDL methods require a response to be sent"]
14820#[derive(Debug)]
14821pub struct NodeGetNodeRefResponder {
14822 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
14823 tx_id: u32,
14824}
14825
14826/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
14827/// if the responder is dropped without sending a response, so that the client
14828/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
14829impl std::ops::Drop for NodeGetNodeRefResponder {
14830 fn drop(&mut self) {
14831 self.control_handle.shutdown();
14832 // Safety: drops once, never accessed again
14833 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14834 }
14835}
14836
14837impl fidl::endpoints::Responder for NodeGetNodeRefResponder {
14838 type ControlHandle = NodeControlHandle;
14839
14840 fn control_handle(&self) -> &NodeControlHandle {
14841 &self.control_handle
14842 }
14843
14844 fn drop_without_shutdown(mut self) {
14845 // Safety: drops once, never accessed again due to mem::forget
14846 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14847 // Prevent Drop from running (which would shut down the channel)
14848 std::mem::forget(self);
14849 }
14850}
14851
14852impl NodeGetNodeRefResponder {
14853 /// Sends a response to the FIDL transaction.
14854 ///
14855 /// Sets the channel to shutdown if an error occurs.
14856 pub fn send(self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
14857 let _result = self.send_raw(payload);
14858 if _result.is_err() {
14859 self.control_handle.shutdown();
14860 }
14861 self.drop_without_shutdown();
14862 _result
14863 }
14864
14865 /// Similar to "send" but does not shutdown the channel if an error occurs.
14866 pub fn send_no_shutdown_on_err(
14867 self,
14868 mut payload: NodeGetNodeRefResponse,
14869 ) -> Result<(), fidl::Error> {
14870 let _result = self.send_raw(payload);
14871 self.drop_without_shutdown();
14872 _result
14873 }
14874
14875 fn send_raw(&self, mut payload: NodeGetNodeRefResponse) -> Result<(), fidl::Error> {
14876 self.control_handle.inner.send::<fidl::encoding::FlexibleType<NodeGetNodeRefResponse>>(
14877 fidl::encoding::Flexible::new(&mut payload),
14878 self.tx_id,
14879 0x5b3d0e51614df053,
14880 fidl::encoding::DynamicFlags::FLEXIBLE,
14881 )
14882 }
14883}
14884
14885#[must_use = "FIDL methods require a response to be sent"]
14886#[derive(Debug)]
14887pub struct NodeIsAlternateForResponder {
14888 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
14889 tx_id: u32,
14890}
14891
14892/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
14893/// if the responder is dropped without sending a response, so that the client
14894/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
14895impl std::ops::Drop for NodeIsAlternateForResponder {
14896 fn drop(&mut self) {
14897 self.control_handle.shutdown();
14898 // Safety: drops once, never accessed again
14899 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14900 }
14901}
14902
14903impl fidl::endpoints::Responder for NodeIsAlternateForResponder {
14904 type ControlHandle = NodeControlHandle;
14905
14906 fn control_handle(&self) -> &NodeControlHandle {
14907 &self.control_handle
14908 }
14909
14910 fn drop_without_shutdown(mut self) {
14911 // Safety: drops once, never accessed again due to mem::forget
14912 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14913 // Prevent Drop from running (which would shut down the channel)
14914 std::mem::forget(self);
14915 }
14916}
14917
14918impl NodeIsAlternateForResponder {
14919 /// Sends a response to the FIDL transaction.
14920 ///
14921 /// Sets the channel to shutdown if an error occurs.
14922 pub fn send(
14923 self,
14924 mut result: Result<&NodeIsAlternateForResponse, Error>,
14925 ) -> Result<(), fidl::Error> {
14926 let _result = self.send_raw(result);
14927 if _result.is_err() {
14928 self.control_handle.shutdown();
14929 }
14930 self.drop_without_shutdown();
14931 _result
14932 }
14933
14934 /// Similar to "send" but does not shutdown the channel if an error occurs.
14935 pub fn send_no_shutdown_on_err(
14936 self,
14937 mut result: Result<&NodeIsAlternateForResponse, Error>,
14938 ) -> Result<(), fidl::Error> {
14939 let _result = self.send_raw(result);
14940 self.drop_without_shutdown();
14941 _result
14942 }
14943
14944 fn send_raw(
14945 &self,
14946 mut result: Result<&NodeIsAlternateForResponse, Error>,
14947 ) -> Result<(), fidl::Error> {
14948 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
14949 NodeIsAlternateForResponse,
14950 Error,
14951 >>(
14952 fidl::encoding::FlexibleResult::new(result),
14953 self.tx_id,
14954 0x3a58e00157e0825,
14955 fidl::encoding::DynamicFlags::FLEXIBLE,
14956 )
14957 }
14958}
14959
14960#[must_use = "FIDL methods require a response to be sent"]
14961#[derive(Debug)]
14962pub struct NodeGetBufferCollectionIdResponder {
14963 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
14964 tx_id: u32,
14965}
14966
14967/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
14968/// if the responder is dropped without sending a response, so that the client
14969/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
14970impl std::ops::Drop for NodeGetBufferCollectionIdResponder {
14971 fn drop(&mut self) {
14972 self.control_handle.shutdown();
14973 // Safety: drops once, never accessed again
14974 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14975 }
14976}
14977
14978impl fidl::endpoints::Responder for NodeGetBufferCollectionIdResponder {
14979 type ControlHandle = NodeControlHandle;
14980
14981 fn control_handle(&self) -> &NodeControlHandle {
14982 &self.control_handle
14983 }
14984
14985 fn drop_without_shutdown(mut self) {
14986 // Safety: drops once, never accessed again due to mem::forget
14987 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
14988 // Prevent Drop from running (which would shut down the channel)
14989 std::mem::forget(self);
14990 }
14991}
14992
14993impl NodeGetBufferCollectionIdResponder {
14994 /// Sends a response to the FIDL transaction.
14995 ///
14996 /// Sets the channel to shutdown if an error occurs.
14997 pub fn send(self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
14998 let _result = self.send_raw(payload);
14999 if _result.is_err() {
15000 self.control_handle.shutdown();
15001 }
15002 self.drop_without_shutdown();
15003 _result
15004 }
15005
15006 /// Similar to "send" but does not shutdown the channel if an error occurs.
15007 pub fn send_no_shutdown_on_err(
15008 self,
15009 mut payload: &NodeGetBufferCollectionIdResponse,
15010 ) -> Result<(), fidl::Error> {
15011 let _result = self.send_raw(payload);
15012 self.drop_without_shutdown();
15013 _result
15014 }
15015
15016 fn send_raw(&self, mut payload: &NodeGetBufferCollectionIdResponse) -> Result<(), fidl::Error> {
15017 self.control_handle
15018 .inner
15019 .send::<fidl::encoding::FlexibleType<NodeGetBufferCollectionIdResponse>>(
15020 fidl::encoding::Flexible::new(payload),
15021 self.tx_id,
15022 0x77d19a494b78ba8c,
15023 fidl::encoding::DynamicFlags::FLEXIBLE,
15024 )
15025 }
15026}
15027
15028#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
15029pub struct SecureMemMarker;
15030
15031impl fidl::endpoints::ProtocolMarker for SecureMemMarker {
15032 type Proxy = SecureMemProxy;
15033 type RequestStream = SecureMemRequestStream;
15034 #[cfg(target_os = "fuchsia")]
15035 type SynchronousProxy = SecureMemSynchronousProxy;
15036
15037 const DEBUG_NAME: &'static str = "(anonymous) SecureMem";
15038}
15039pub type SecureMemGetPhysicalSecureHeapsResult =
15040 Result<SecureMemGetPhysicalSecureHeapsResponse, Error>;
15041pub type SecureMemGetDynamicSecureHeapsResult =
15042 Result<SecureMemGetDynamicSecureHeapsResponse, Error>;
15043pub type SecureMemGetPhysicalSecureHeapPropertiesResult =
15044 Result<SecureMemGetPhysicalSecureHeapPropertiesResponse, Error>;
15045pub type SecureMemAddSecureHeapPhysicalRangeResult = Result<(), Error>;
15046pub type SecureMemDeleteSecureHeapPhysicalRangeResult = Result<(), Error>;
15047pub type SecureMemModifySecureHeapPhysicalRangeResult = Result<(), Error>;
15048pub type SecureMemZeroSubRangeResult = Result<(), Error>;
15049
15050pub trait SecureMemProxyInterface: Send + Sync {
15051 type GetPhysicalSecureHeapsResponseFut: std::future::Future<Output = Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error>>
15052 + Send;
15053 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut;
15054 type GetDynamicSecureHeapsResponseFut: std::future::Future<Output = Result<SecureMemGetDynamicSecureHeapsResult, fidl::Error>>
15055 + Send;
15056 fn r#get_dynamic_secure_heaps(&self) -> Self::GetDynamicSecureHeapsResponseFut;
15057 type GetPhysicalSecureHeapPropertiesResponseFut: std::future::Future<
15058 Output = Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error>,
15059 > + Send;
15060 fn r#get_physical_secure_heap_properties(
15061 &self,
15062 payload: &SecureMemGetPhysicalSecureHeapPropertiesRequest,
15063 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut;
15064 type AddSecureHeapPhysicalRangeResponseFut: std::future::Future<Output = Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error>>
15065 + Send;
15066 fn r#add_secure_heap_physical_range(
15067 &self,
15068 payload: &SecureMemAddSecureHeapPhysicalRangeRequest,
15069 ) -> Self::AddSecureHeapPhysicalRangeResponseFut;
15070 type DeleteSecureHeapPhysicalRangeResponseFut: std::future::Future<
15071 Output = Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error>,
15072 > + Send;
15073 fn r#delete_secure_heap_physical_range(
15074 &self,
15075 payload: &SecureMemDeleteSecureHeapPhysicalRangeRequest,
15076 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut;
15077 type ModifySecureHeapPhysicalRangeResponseFut: std::future::Future<
15078 Output = Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error>,
15079 > + Send;
15080 fn r#modify_secure_heap_physical_range(
15081 &self,
15082 payload: &SecureMemModifySecureHeapPhysicalRangeRequest,
15083 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut;
15084 type ZeroSubRangeResponseFut: std::future::Future<Output = Result<SecureMemZeroSubRangeResult, fidl::Error>>
15085 + Send;
15086 fn r#zero_sub_range(
15087 &self,
15088 payload: &SecureMemZeroSubRangeRequest,
15089 ) -> Self::ZeroSubRangeResponseFut;
15090}
15091#[derive(Debug)]
15092#[cfg(target_os = "fuchsia")]
15093pub struct SecureMemSynchronousProxy {
15094 client: fidl::client::sync::Client,
15095}
15096
15097#[cfg(target_os = "fuchsia")]
15098impl fidl::endpoints::SynchronousProxy for SecureMemSynchronousProxy {
15099 type Proxy = SecureMemProxy;
15100 type Protocol = SecureMemMarker;
15101
15102 fn from_channel(inner: fidl::Channel) -> Self {
15103 Self::new(inner)
15104 }
15105
15106 fn into_channel(self) -> fidl::Channel {
15107 self.client.into_channel()
15108 }
15109
15110 fn as_channel(&self) -> &fidl::Channel {
15111 self.client.as_channel()
15112 }
15113}
15114
15115#[cfg(target_os = "fuchsia")]
15116impl SecureMemSynchronousProxy {
15117 pub fn new(channel: fidl::Channel) -> Self {
15118 Self { client: fidl::client::sync::Client::new(channel) }
15119 }
15120
15121 pub fn into_channel(self) -> fidl::Channel {
15122 self.client.into_channel()
15123 }
15124
15125 /// Waits until an event arrives and returns it. It is safe for other
15126 /// threads to make concurrent requests while waiting for an event.
15127 pub fn wait_for_event(
15128 &self,
15129 deadline: zx::MonotonicInstant,
15130 ) -> Result<SecureMemEvent, fidl::Error> {
15131 SecureMemEvent::decode(self.client.wait_for_event::<SecureMemMarker>(deadline)?)
15132 }
15133
15134 /// Gets the physical address and length of any secure heap whose physical
15135 /// range is configured via the TEE.
15136 ///
15137 /// Presently, these will be fixed physical addresses and lengths, with the
15138 /// location plumbed via the TEE.
15139 ///
15140 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
15141 /// when there isn't any special heap-specific per-VMO setup or teardown
15142 /// required.
15143 ///
15144 /// The physical range must be secured/protected by the TEE before the
15145 /// securemem driver responds to this request with success.
15146 ///
15147 /// Sysmem should only call this once. Returning zero heaps is not a
15148 /// failure.
15149 ///
15150 /// Errors:
15151 /// * PROTOCOL_DEVIATION - called more than once.
15152 /// * UNSPECIFIED - generic internal error (such as in communication
15153 /// with TEE which doesn't generate zx_status_t errors).
15154 /// * other errors are allowed; any other errors should be treated the same
15155 /// as UNSPECIFIED.
15156 pub fn r#get_physical_secure_heaps(
15157 &self,
15158 ___deadline: zx::MonotonicInstant,
15159 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
15160 let _response = self.client.send_query::<
15161 fidl::encoding::EmptyPayload,
15162 fidl::encoding::FlexibleResultType<SecureMemGetPhysicalSecureHeapsResponse, Error>,
15163 SecureMemMarker,
15164 >(
15165 (),
15166 0x38716300592073e3,
15167 fidl::encoding::DynamicFlags::FLEXIBLE,
15168 ___deadline,
15169 )?
15170 .into_result::<SecureMemMarker>("get_physical_secure_heaps")?;
15171 Ok(_response.map(|x| x))
15172 }
15173
15174 /// Gets information about any secure heaps whose physical pages are not
15175 /// configured by the TEE, but by sysmem.
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_dynamic_secure_heaps(
15187 &self,
15188 ___deadline: zx::MonotonicInstant,
15189 ) -> Result<SecureMemGetDynamicSecureHeapsResult, fidl::Error> {
15190 let _response = self.client.send_query::<
15191 fidl::encoding::EmptyPayload,
15192 fidl::encoding::FlexibleResultType<SecureMemGetDynamicSecureHeapsResponse, Error>,
15193 SecureMemMarker,
15194 >(
15195 (),
15196 0x1190847f99952834,
15197 fidl::encoding::DynamicFlags::FLEXIBLE,
15198 ___deadline,
15199 )?
15200 .into_result::<SecureMemMarker>("get_dynamic_secure_heaps")?;
15201 Ok(_response.map(|x| x))
15202 }
15203
15204 /// This request from sysmem to the securemem driver gets the properties of
15205 /// a protected/secure heap.
15206 ///
15207 /// This only handles heaps with a single contiguous physical extent.
15208 ///
15209 /// The heap's entire physical range is indicated in case this request needs
15210 /// some physical space to auto-detect how many ranges are REE-usable. Any
15211 /// temporary HW protection ranges will be deleted before this request
15212 /// completes.
15213 ///
15214 /// Errors:
15215 /// * UNSPECIFIED - generic internal error (such as in communication
15216 /// with TEE which doesn't generate zx_status_t errors).
15217 /// * other errors are allowed; any other errors should be treated the same
15218 /// as UNSPECIFIED.
15219 pub fn r#get_physical_secure_heap_properties(
15220 &self,
15221 mut payload: &SecureMemGetPhysicalSecureHeapPropertiesRequest,
15222 ___deadline: zx::MonotonicInstant,
15223 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
15224 let _response = self.client.send_query::<
15225 SecureMemGetPhysicalSecureHeapPropertiesRequest,
15226 fidl::encoding::FlexibleResultType<SecureMemGetPhysicalSecureHeapPropertiesResponse, Error>,
15227 SecureMemMarker,
15228 >(
15229 payload,
15230 0xc6f06889009c7bc,
15231 fidl::encoding::DynamicFlags::FLEXIBLE,
15232 ___deadline,
15233 )?
15234 .into_result::<SecureMemMarker>("get_physical_secure_heap_properties")?;
15235 Ok(_response.map(|x| x))
15236 }
15237
15238 /// This request from sysmem to the securemem driver conveys a physical
15239 /// range to add, for a heap whose physical range(s) are set up via
15240 /// sysmem.
15241 ///
15242 /// Only sysmem can call this because only sysmem is handed the client end
15243 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15244 /// securemem driver is the server end of this protocol.
15245 ///
15246 /// The securemem driver must configure all the covered offsets as protected
15247 /// before responding to this message with success.
15248 ///
15249 /// On failure, the securemem driver must ensure the protected range was not
15250 /// created.
15251 ///
15252 /// Sysmem must only call this up to once if dynamic_protection_ranges
15253 /// false.
15254 ///
15255 /// If dynamic_protection_ranges is true, sysmem can call this multiple
15256 /// times as long as the current number of ranges never exceeds
15257 /// max_protected_range_count.
15258 ///
15259 /// The caller must not attempt to add a range that matches an
15260 /// already-existing range. Added ranges can overlap each other as long as
15261 /// no two ranges match exactly.
15262 ///
15263 /// Errors:
15264 /// * PROTOCOL_DEVIATION - called more than once when
15265 /// !dynamic_protection_ranges. Adding a heap that would cause overall
15266 /// heap count to exceed max_protected_range_count. Unexpected heap, or
15267 /// range that doesn't conform to protected_range_granularity. See log.
15268 /// * UNSPECIFIED - generic internal error (such as in communication
15269 /// with TEE which doesn't generate zx_status_t errors).
15270 /// * other errors are possible, such as from communication failures or
15271 /// server propagation of failures.
15272 pub fn r#add_secure_heap_physical_range(
15273 &self,
15274 mut payload: &SecureMemAddSecureHeapPhysicalRangeRequest,
15275 ___deadline: zx::MonotonicInstant,
15276 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
15277 let _response = self.client.send_query::<
15278 SecureMemAddSecureHeapPhysicalRangeRequest,
15279 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15280 SecureMemMarker,
15281 >(
15282 payload,
15283 0x35f695b9b6c7217a,
15284 fidl::encoding::DynamicFlags::FLEXIBLE,
15285 ___deadline,
15286 )?
15287 .into_result::<SecureMemMarker>("add_secure_heap_physical_range")?;
15288 Ok(_response.map(|x| x))
15289 }
15290
15291 /// This request from sysmem to the securemem driver conveys a physical
15292 /// range to delete, for a heap whose physical range(s) are set up via
15293 /// sysmem.
15294 ///
15295 /// Only sysmem can call this because only sysmem is handed the client end
15296 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15297 /// securemem driver is the server end of this protocol.
15298 ///
15299 /// The securemem driver must configure all the covered offsets as not
15300 /// protected before responding to this message with success.
15301 ///
15302 /// On failure, the securemem driver must ensure the protected range was not
15303 /// deleted.
15304 ///
15305 /// Sysmem must not call this if dynamic_protection_ranges false.
15306 ///
15307 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
15308 /// on various ranges that exist at the time of the call.
15309 ///
15310 /// If any portion of the range being deleted is not also covered by another
15311 /// protected range, then any ongoing DMA to any part of the entire range
15312 /// may be interrupted / may fail, potentially in a way that's disruptive to
15313 /// the entire system (bus lockup or similar, depending on device details).
15314 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
15315 /// any portion of the range being deleted, unless the caller has other
15316 /// active ranges covering every block of the range being deleted. Ongoing
15317 /// DMA to/from blocks outside the range being deleted is never impacted by
15318 /// the deletion.
15319 ///
15320 /// Errors:
15321 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15322 /// Unexpected heap, or range that doesn't conform to
15323 /// protected_range_granularity.
15324 /// * UNSPECIFIED - generic internal error (such as in communication
15325 /// with TEE which doesn't generate zx_status_t errors).
15326 /// * NOT_FOUND - the specified range is not found.
15327 /// * other errors are possible, such as from communication failures or
15328 /// server propagation of failures.
15329 pub fn r#delete_secure_heap_physical_range(
15330 &self,
15331 mut payload: &SecureMemDeleteSecureHeapPhysicalRangeRequest,
15332 ___deadline: zx::MonotonicInstant,
15333 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
15334 let _response = self.client.send_query::<
15335 SecureMemDeleteSecureHeapPhysicalRangeRequest,
15336 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15337 SecureMemMarker,
15338 >(
15339 payload,
15340 0xeaa58c650264c9e,
15341 fidl::encoding::DynamicFlags::FLEXIBLE,
15342 ___deadline,
15343 )?
15344 .into_result::<SecureMemMarker>("delete_secure_heap_physical_range")?;
15345 Ok(_response.map(|x| x))
15346 }
15347
15348 /// This request from sysmem to the securemem driver conveys a physical
15349 /// range to modify and its new base and length, for a heap whose physical
15350 /// range(s) are set up via sysmem.
15351 ///
15352 /// Only sysmem can call this because only sysmem is handed the client end
15353 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15354 /// securemem driver is the server end of this protocol.
15355 ///
15356 /// The securemem driver must configure the range to cover only the new
15357 /// offsets before responding to this message with success.
15358 ///
15359 /// On failure, the securemem driver must ensure the range was not changed.
15360 ///
15361 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
15362 /// must not call this if !is_mod_protected_range_available.
15363 ///
15364 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
15365 /// on various ranges that exist at the time of the call.
15366 ///
15367 /// The range must only be modified at one end or the other, but not both.
15368 /// If the range is getting shorter, and the un-covered blocks are not
15369 /// covered by other active ranges, any ongoing DMA to the entire range
15370 /// that's geting shorter may fail in a way that disrupts the entire system
15371 /// (bus lockup or similar), so the caller must ensure that no DMA is
15372 /// ongoing to any portion of a range that is getting shorter, unless the
15373 /// blocks being un-covered by the modification to this range are all
15374 /// covered by other active ranges, in which case no disruption to ongoing
15375 /// DMA will occur.
15376 ///
15377 /// If a range is modified to become <= zero length, the range is deleted.
15378 ///
15379 /// Errors:
15380 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15381 /// Unexpected heap, or old_range or new_range that doesn't conform to
15382 /// protected_range_granularity, or old_range and new_range differ in
15383 /// both begin and end (disallowed).
15384 /// * UNSPECIFIED - generic internal error (such as in communication
15385 /// with TEE which doesn't generate zx_status_t errors).
15386 /// * NOT_FOUND - the specified range is not found.
15387 /// * other errors are possible, such as from communication failures or
15388 /// server propagation of failures.
15389 pub fn r#modify_secure_heap_physical_range(
15390 &self,
15391 mut payload: &SecureMemModifySecureHeapPhysicalRangeRequest,
15392 ___deadline: zx::MonotonicInstant,
15393 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
15394 let _response = self.client.send_query::<
15395 SecureMemModifySecureHeapPhysicalRangeRequest,
15396 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15397 SecureMemMarker,
15398 >(
15399 payload,
15400 0x60b7448aa1187734,
15401 fidl::encoding::DynamicFlags::FLEXIBLE,
15402 ___deadline,
15403 )?
15404 .into_result::<SecureMemMarker>("modify_secure_heap_physical_range")?;
15405 Ok(_response.map(|x| x))
15406 }
15407
15408 /// Zero a sub-range of a currently-existing physical range added via
15409 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
15410 /// exactly one physical range, and must not overlap with any other
15411 /// physical range.
15412 ///
15413 /// is_covering_range_explicit - When true, the covering range must be one
15414 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
15415 /// possibly modified since. When false, the covering range must not
15416 /// be one of the ranges explicitly created via
15417 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
15418 /// a covering range not created via AddSecureHeapPhysicalRange(). The
15419 /// covering range is typically the entire physical range (or a range
15420 /// which covers even more) of a heap configured by the TEE and whose
15421 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
15422 ///
15423 /// Ongoing DMA is not disrupted by this request.
15424 ///
15425 /// Errors:
15426 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15427 /// Unexpected heap.
15428 /// * UNSPECIFIED - generic internal error (such as in communication
15429 /// with TEE which doesn't generate zx_status_t errors).
15430 /// * other errors are possible, such as from communication failures or
15431 /// server propagation of failures.
15432 pub fn r#zero_sub_range(
15433 &self,
15434 mut payload: &SecureMemZeroSubRangeRequest,
15435 ___deadline: zx::MonotonicInstant,
15436 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
15437 let _response = self.client.send_query::<
15438 SecureMemZeroSubRangeRequest,
15439 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15440 SecureMemMarker,
15441 >(
15442 payload,
15443 0x5b25b7901a385ce5,
15444 fidl::encoding::DynamicFlags::FLEXIBLE,
15445 ___deadline,
15446 )?
15447 .into_result::<SecureMemMarker>("zero_sub_range")?;
15448 Ok(_response.map(|x| x))
15449 }
15450}
15451
15452#[cfg(target_os = "fuchsia")]
15453impl From<SecureMemSynchronousProxy> for zx::NullableHandle {
15454 fn from(value: SecureMemSynchronousProxy) -> Self {
15455 value.into_channel().into()
15456 }
15457}
15458
15459#[cfg(target_os = "fuchsia")]
15460impl From<fidl::Channel> for SecureMemSynchronousProxy {
15461 fn from(value: fidl::Channel) -> Self {
15462 Self::new(value)
15463 }
15464}
15465
15466#[cfg(target_os = "fuchsia")]
15467impl fidl::endpoints::FromClient for SecureMemSynchronousProxy {
15468 type Protocol = SecureMemMarker;
15469
15470 fn from_client(value: fidl::endpoints::ClientEnd<SecureMemMarker>) -> Self {
15471 Self::new(value.into_channel())
15472 }
15473}
15474
15475#[derive(Debug, Clone)]
15476pub struct SecureMemProxy {
15477 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
15478}
15479
15480impl fidl::endpoints::Proxy for SecureMemProxy {
15481 type Protocol = SecureMemMarker;
15482
15483 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
15484 Self::new(inner)
15485 }
15486
15487 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
15488 self.client.into_channel().map_err(|client| Self { client })
15489 }
15490
15491 fn as_channel(&self) -> &::fidl::AsyncChannel {
15492 self.client.as_channel()
15493 }
15494}
15495
15496impl SecureMemProxy {
15497 /// Create a new Proxy for fuchsia.sysmem2/SecureMem.
15498 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
15499 let protocol_name = <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
15500 Self { client: fidl::client::Client::new(channel, protocol_name) }
15501 }
15502
15503 /// Get a Stream of events from the remote end of the protocol.
15504 ///
15505 /// # Panics
15506 ///
15507 /// Panics if the event stream was already taken.
15508 pub fn take_event_stream(&self) -> SecureMemEventStream {
15509 SecureMemEventStream { event_receiver: self.client.take_event_receiver() }
15510 }
15511
15512 /// Gets the physical address and length of any secure heap whose physical
15513 /// range is configured via the TEE.
15514 ///
15515 /// Presently, these will be fixed physical addresses and lengths, with the
15516 /// location plumbed via the TEE.
15517 ///
15518 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
15519 /// when there isn't any special heap-specific per-VMO setup or teardown
15520 /// required.
15521 ///
15522 /// The physical range must be secured/protected by the TEE before the
15523 /// securemem driver responds to this request with success.
15524 ///
15525 /// Sysmem should only call this once. Returning zero heaps is not a
15526 /// failure.
15527 ///
15528 /// Errors:
15529 /// * PROTOCOL_DEVIATION - called more than once.
15530 /// * UNSPECIFIED - generic internal error (such as in communication
15531 /// with TEE which doesn't generate zx_status_t errors).
15532 /// * other errors are allowed; any other errors should be treated the same
15533 /// as UNSPECIFIED.
15534 pub fn r#get_physical_secure_heaps(
15535 &self,
15536 ) -> fidl::client::QueryResponseFut<
15537 SecureMemGetPhysicalSecureHeapsResult,
15538 fidl::encoding::DefaultFuchsiaResourceDialect,
15539 > {
15540 SecureMemProxyInterface::r#get_physical_secure_heaps(self)
15541 }
15542
15543 /// Gets information about any secure heaps whose physical pages are not
15544 /// configured by the TEE, but by sysmem.
15545 ///
15546 /// Sysmem should only call this once. Returning zero heaps is not a
15547 /// failure.
15548 ///
15549 /// Errors:
15550 /// * PROTOCOL_DEVIATION - called more than once.
15551 /// * UNSPECIFIED - generic internal error (such as in communication
15552 /// with TEE which doesn't generate zx_status_t errors).
15553 /// * other errors are allowed; any other errors should be treated the same
15554 /// as UNSPECIFIED.
15555 pub fn r#get_dynamic_secure_heaps(
15556 &self,
15557 ) -> fidl::client::QueryResponseFut<
15558 SecureMemGetDynamicSecureHeapsResult,
15559 fidl::encoding::DefaultFuchsiaResourceDialect,
15560 > {
15561 SecureMemProxyInterface::r#get_dynamic_secure_heaps(self)
15562 }
15563
15564 /// This request from sysmem to the securemem driver gets the properties of
15565 /// a protected/secure heap.
15566 ///
15567 /// This only handles heaps with a single contiguous physical extent.
15568 ///
15569 /// The heap's entire physical range is indicated in case this request needs
15570 /// some physical space to auto-detect how many ranges are REE-usable. Any
15571 /// temporary HW protection ranges will be deleted before this request
15572 /// completes.
15573 ///
15574 /// Errors:
15575 /// * UNSPECIFIED - generic internal error (such as in communication
15576 /// with TEE which doesn't generate zx_status_t errors).
15577 /// * other errors are allowed; any other errors should be treated the same
15578 /// as UNSPECIFIED.
15579 pub fn r#get_physical_secure_heap_properties(
15580 &self,
15581 mut payload: &SecureMemGetPhysicalSecureHeapPropertiesRequest,
15582 ) -> fidl::client::QueryResponseFut<
15583 SecureMemGetPhysicalSecureHeapPropertiesResult,
15584 fidl::encoding::DefaultFuchsiaResourceDialect,
15585 > {
15586 SecureMemProxyInterface::r#get_physical_secure_heap_properties(self, payload)
15587 }
15588
15589 /// This request from sysmem to the securemem driver conveys a physical
15590 /// range to add, for a heap whose physical range(s) are set up via
15591 /// sysmem.
15592 ///
15593 /// Only sysmem can call this because only sysmem is handed the client end
15594 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15595 /// securemem driver is the server end of this protocol.
15596 ///
15597 /// The securemem driver must configure all the covered offsets as protected
15598 /// before responding to this message with success.
15599 ///
15600 /// On failure, the securemem driver must ensure the protected range was not
15601 /// created.
15602 ///
15603 /// Sysmem must only call this up to once if dynamic_protection_ranges
15604 /// false.
15605 ///
15606 /// If dynamic_protection_ranges is true, sysmem can call this multiple
15607 /// times as long as the current number of ranges never exceeds
15608 /// max_protected_range_count.
15609 ///
15610 /// The caller must not attempt to add a range that matches an
15611 /// already-existing range. Added ranges can overlap each other as long as
15612 /// no two ranges match exactly.
15613 ///
15614 /// Errors:
15615 /// * PROTOCOL_DEVIATION - called more than once when
15616 /// !dynamic_protection_ranges. Adding a heap that would cause overall
15617 /// heap count to exceed max_protected_range_count. Unexpected heap, or
15618 /// range that doesn't conform to protected_range_granularity. See log.
15619 /// * UNSPECIFIED - generic internal error (such as in communication
15620 /// with TEE which doesn't generate zx_status_t errors).
15621 /// * other errors are possible, such as from communication failures or
15622 /// server propagation of failures.
15623 pub fn r#add_secure_heap_physical_range(
15624 &self,
15625 mut payload: &SecureMemAddSecureHeapPhysicalRangeRequest,
15626 ) -> fidl::client::QueryResponseFut<
15627 SecureMemAddSecureHeapPhysicalRangeResult,
15628 fidl::encoding::DefaultFuchsiaResourceDialect,
15629 > {
15630 SecureMemProxyInterface::r#add_secure_heap_physical_range(self, payload)
15631 }
15632
15633 /// This request from sysmem to the securemem driver conveys a physical
15634 /// range to delete, for a heap whose physical range(s) are set up via
15635 /// sysmem.
15636 ///
15637 /// Only sysmem can call this because only sysmem is handed the client end
15638 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15639 /// securemem driver is the server end of this protocol.
15640 ///
15641 /// The securemem driver must configure all the covered offsets as not
15642 /// protected before responding to this message with success.
15643 ///
15644 /// On failure, the securemem driver must ensure the protected range was not
15645 /// deleted.
15646 ///
15647 /// Sysmem must not call this if dynamic_protection_ranges false.
15648 ///
15649 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
15650 /// on various ranges that exist at the time of the call.
15651 ///
15652 /// If any portion of the range being deleted is not also covered by another
15653 /// protected range, then any ongoing DMA to any part of the entire range
15654 /// may be interrupted / may fail, potentially in a way that's disruptive to
15655 /// the entire system (bus lockup or similar, depending on device details).
15656 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
15657 /// any portion of the range being deleted, unless the caller has other
15658 /// active ranges covering every block of the range being deleted. Ongoing
15659 /// DMA to/from blocks outside the range being deleted is never impacted by
15660 /// the deletion.
15661 ///
15662 /// Errors:
15663 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15664 /// Unexpected heap, or range that doesn't conform to
15665 /// protected_range_granularity.
15666 /// * UNSPECIFIED - generic internal error (such as in communication
15667 /// with TEE which doesn't generate zx_status_t errors).
15668 /// * NOT_FOUND - the specified range is not found.
15669 /// * other errors are possible, such as from communication failures or
15670 /// server propagation of failures.
15671 pub fn r#delete_secure_heap_physical_range(
15672 &self,
15673 mut payload: &SecureMemDeleteSecureHeapPhysicalRangeRequest,
15674 ) -> fidl::client::QueryResponseFut<
15675 SecureMemDeleteSecureHeapPhysicalRangeResult,
15676 fidl::encoding::DefaultFuchsiaResourceDialect,
15677 > {
15678 SecureMemProxyInterface::r#delete_secure_heap_physical_range(self, payload)
15679 }
15680
15681 /// This request from sysmem to the securemem driver conveys a physical
15682 /// range to modify and its new base and length, for a heap whose physical
15683 /// range(s) are set up via sysmem.
15684 ///
15685 /// Only sysmem can call this because only sysmem is handed the client end
15686 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
15687 /// securemem driver is the server end of this protocol.
15688 ///
15689 /// The securemem driver must configure the range to cover only the new
15690 /// offsets before responding to this message with success.
15691 ///
15692 /// On failure, the securemem driver must ensure the range was not changed.
15693 ///
15694 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
15695 /// must not call this if !is_mod_protected_range_available.
15696 ///
15697 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
15698 /// on various ranges that exist at the time of the call.
15699 ///
15700 /// The range must only be modified at one end or the other, but not both.
15701 /// If the range is getting shorter, and the un-covered blocks are not
15702 /// covered by other active ranges, any ongoing DMA to the entire range
15703 /// that's geting shorter may fail in a way that disrupts the entire system
15704 /// (bus lockup or similar), so the caller must ensure that no DMA is
15705 /// ongoing to any portion of a range that is getting shorter, unless the
15706 /// blocks being un-covered by the modification to this range are all
15707 /// covered by other active ranges, in which case no disruption to ongoing
15708 /// DMA will occur.
15709 ///
15710 /// If a range is modified to become <= zero length, the range is deleted.
15711 ///
15712 /// Errors:
15713 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15714 /// Unexpected heap, or old_range or new_range that doesn't conform to
15715 /// protected_range_granularity, or old_range and new_range differ in
15716 /// both begin and end (disallowed).
15717 /// * UNSPECIFIED - generic internal error (such as in communication
15718 /// with TEE which doesn't generate zx_status_t errors).
15719 /// * NOT_FOUND - the specified range is not found.
15720 /// * other errors are possible, such as from communication failures or
15721 /// server propagation of failures.
15722 pub fn r#modify_secure_heap_physical_range(
15723 &self,
15724 mut payload: &SecureMemModifySecureHeapPhysicalRangeRequest,
15725 ) -> fidl::client::QueryResponseFut<
15726 SecureMemModifySecureHeapPhysicalRangeResult,
15727 fidl::encoding::DefaultFuchsiaResourceDialect,
15728 > {
15729 SecureMemProxyInterface::r#modify_secure_heap_physical_range(self, payload)
15730 }
15731
15732 /// Zero a sub-range of a currently-existing physical range added via
15733 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
15734 /// exactly one physical range, and must not overlap with any other
15735 /// physical range.
15736 ///
15737 /// is_covering_range_explicit - When true, the covering range must be one
15738 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
15739 /// possibly modified since. When false, the covering range must not
15740 /// be one of the ranges explicitly created via
15741 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
15742 /// a covering range not created via AddSecureHeapPhysicalRange(). The
15743 /// covering range is typically the entire physical range (or a range
15744 /// which covers even more) of a heap configured by the TEE and whose
15745 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
15746 ///
15747 /// Ongoing DMA is not disrupted by this request.
15748 ///
15749 /// Errors:
15750 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
15751 /// Unexpected heap.
15752 /// * UNSPECIFIED - generic internal error (such as in communication
15753 /// with TEE which doesn't generate zx_status_t errors).
15754 /// * other errors are possible, such as from communication failures or
15755 /// server propagation of failures.
15756 pub fn r#zero_sub_range(
15757 &self,
15758 mut payload: &SecureMemZeroSubRangeRequest,
15759 ) -> fidl::client::QueryResponseFut<
15760 SecureMemZeroSubRangeResult,
15761 fidl::encoding::DefaultFuchsiaResourceDialect,
15762 > {
15763 SecureMemProxyInterface::r#zero_sub_range(self, payload)
15764 }
15765}
15766
15767impl SecureMemProxyInterface for SecureMemProxy {
15768 type GetPhysicalSecureHeapsResponseFut = fidl::client::QueryResponseFut<
15769 SecureMemGetPhysicalSecureHeapsResult,
15770 fidl::encoding::DefaultFuchsiaResourceDialect,
15771 >;
15772 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut {
15773 fn _decode(
15774 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15775 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
15776 let _response = fidl::client::decode_transaction_body::<
15777 fidl::encoding::FlexibleResultType<SecureMemGetPhysicalSecureHeapsResponse, Error>,
15778 fidl::encoding::DefaultFuchsiaResourceDialect,
15779 0x38716300592073e3,
15780 >(_buf?)?
15781 .into_result::<SecureMemMarker>("get_physical_secure_heaps")?;
15782 Ok(_response.map(|x| x))
15783 }
15784 self.client.send_query_and_decode::<
15785 fidl::encoding::EmptyPayload,
15786 SecureMemGetPhysicalSecureHeapsResult,
15787 >(
15788 (),
15789 0x38716300592073e3,
15790 fidl::encoding::DynamicFlags::FLEXIBLE,
15791 _decode,
15792 )
15793 }
15794
15795 type GetDynamicSecureHeapsResponseFut = fidl::client::QueryResponseFut<
15796 SecureMemGetDynamicSecureHeapsResult,
15797 fidl::encoding::DefaultFuchsiaResourceDialect,
15798 >;
15799 fn r#get_dynamic_secure_heaps(&self) -> Self::GetDynamicSecureHeapsResponseFut {
15800 fn _decode(
15801 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15802 ) -> Result<SecureMemGetDynamicSecureHeapsResult, fidl::Error> {
15803 let _response = fidl::client::decode_transaction_body::<
15804 fidl::encoding::FlexibleResultType<SecureMemGetDynamicSecureHeapsResponse, Error>,
15805 fidl::encoding::DefaultFuchsiaResourceDialect,
15806 0x1190847f99952834,
15807 >(_buf?)?
15808 .into_result::<SecureMemMarker>("get_dynamic_secure_heaps")?;
15809 Ok(_response.map(|x| x))
15810 }
15811 self.client.send_query_and_decode::<
15812 fidl::encoding::EmptyPayload,
15813 SecureMemGetDynamicSecureHeapsResult,
15814 >(
15815 (),
15816 0x1190847f99952834,
15817 fidl::encoding::DynamicFlags::FLEXIBLE,
15818 _decode,
15819 )
15820 }
15821
15822 type GetPhysicalSecureHeapPropertiesResponseFut = fidl::client::QueryResponseFut<
15823 SecureMemGetPhysicalSecureHeapPropertiesResult,
15824 fidl::encoding::DefaultFuchsiaResourceDialect,
15825 >;
15826 fn r#get_physical_secure_heap_properties(
15827 &self,
15828 mut payload: &SecureMemGetPhysicalSecureHeapPropertiesRequest,
15829 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut {
15830 fn _decode(
15831 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15832 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
15833 let _response = fidl::client::decode_transaction_body::<
15834 fidl::encoding::FlexibleResultType<
15835 SecureMemGetPhysicalSecureHeapPropertiesResponse,
15836 Error,
15837 >,
15838 fidl::encoding::DefaultFuchsiaResourceDialect,
15839 0xc6f06889009c7bc,
15840 >(_buf?)?
15841 .into_result::<SecureMemMarker>("get_physical_secure_heap_properties")?;
15842 Ok(_response.map(|x| x))
15843 }
15844 self.client.send_query_and_decode::<
15845 SecureMemGetPhysicalSecureHeapPropertiesRequest,
15846 SecureMemGetPhysicalSecureHeapPropertiesResult,
15847 >(
15848 payload,
15849 0xc6f06889009c7bc,
15850 fidl::encoding::DynamicFlags::FLEXIBLE,
15851 _decode,
15852 )
15853 }
15854
15855 type AddSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
15856 SecureMemAddSecureHeapPhysicalRangeResult,
15857 fidl::encoding::DefaultFuchsiaResourceDialect,
15858 >;
15859 fn r#add_secure_heap_physical_range(
15860 &self,
15861 mut payload: &SecureMemAddSecureHeapPhysicalRangeRequest,
15862 ) -> Self::AddSecureHeapPhysicalRangeResponseFut {
15863 fn _decode(
15864 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15865 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
15866 let _response = fidl::client::decode_transaction_body::<
15867 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15868 fidl::encoding::DefaultFuchsiaResourceDialect,
15869 0x35f695b9b6c7217a,
15870 >(_buf?)?
15871 .into_result::<SecureMemMarker>("add_secure_heap_physical_range")?;
15872 Ok(_response.map(|x| x))
15873 }
15874 self.client.send_query_and_decode::<
15875 SecureMemAddSecureHeapPhysicalRangeRequest,
15876 SecureMemAddSecureHeapPhysicalRangeResult,
15877 >(
15878 payload,
15879 0x35f695b9b6c7217a,
15880 fidl::encoding::DynamicFlags::FLEXIBLE,
15881 _decode,
15882 )
15883 }
15884
15885 type DeleteSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
15886 SecureMemDeleteSecureHeapPhysicalRangeResult,
15887 fidl::encoding::DefaultFuchsiaResourceDialect,
15888 >;
15889 fn r#delete_secure_heap_physical_range(
15890 &self,
15891 mut payload: &SecureMemDeleteSecureHeapPhysicalRangeRequest,
15892 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut {
15893 fn _decode(
15894 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15895 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
15896 let _response = fidl::client::decode_transaction_body::<
15897 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15898 fidl::encoding::DefaultFuchsiaResourceDialect,
15899 0xeaa58c650264c9e,
15900 >(_buf?)?
15901 .into_result::<SecureMemMarker>("delete_secure_heap_physical_range")?;
15902 Ok(_response.map(|x| x))
15903 }
15904 self.client.send_query_and_decode::<
15905 SecureMemDeleteSecureHeapPhysicalRangeRequest,
15906 SecureMemDeleteSecureHeapPhysicalRangeResult,
15907 >(
15908 payload,
15909 0xeaa58c650264c9e,
15910 fidl::encoding::DynamicFlags::FLEXIBLE,
15911 _decode,
15912 )
15913 }
15914
15915 type ModifySecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
15916 SecureMemModifySecureHeapPhysicalRangeResult,
15917 fidl::encoding::DefaultFuchsiaResourceDialect,
15918 >;
15919 fn r#modify_secure_heap_physical_range(
15920 &self,
15921 mut payload: &SecureMemModifySecureHeapPhysicalRangeRequest,
15922 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut {
15923 fn _decode(
15924 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15925 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
15926 let _response = fidl::client::decode_transaction_body::<
15927 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15928 fidl::encoding::DefaultFuchsiaResourceDialect,
15929 0x60b7448aa1187734,
15930 >(_buf?)?
15931 .into_result::<SecureMemMarker>("modify_secure_heap_physical_range")?;
15932 Ok(_response.map(|x| x))
15933 }
15934 self.client.send_query_and_decode::<
15935 SecureMemModifySecureHeapPhysicalRangeRequest,
15936 SecureMemModifySecureHeapPhysicalRangeResult,
15937 >(
15938 payload,
15939 0x60b7448aa1187734,
15940 fidl::encoding::DynamicFlags::FLEXIBLE,
15941 _decode,
15942 )
15943 }
15944
15945 type ZeroSubRangeResponseFut = fidl::client::QueryResponseFut<
15946 SecureMemZeroSubRangeResult,
15947 fidl::encoding::DefaultFuchsiaResourceDialect,
15948 >;
15949 fn r#zero_sub_range(
15950 &self,
15951 mut payload: &SecureMemZeroSubRangeRequest,
15952 ) -> Self::ZeroSubRangeResponseFut {
15953 fn _decode(
15954 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
15955 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
15956 let _response = fidl::client::decode_transaction_body::<
15957 fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
15958 fidl::encoding::DefaultFuchsiaResourceDialect,
15959 0x5b25b7901a385ce5,
15960 >(_buf?)?
15961 .into_result::<SecureMemMarker>("zero_sub_range")?;
15962 Ok(_response.map(|x| x))
15963 }
15964 self.client
15965 .send_query_and_decode::<SecureMemZeroSubRangeRequest, SecureMemZeroSubRangeResult>(
15966 payload,
15967 0x5b25b7901a385ce5,
15968 fidl::encoding::DynamicFlags::FLEXIBLE,
15969 _decode,
15970 )
15971 }
15972}
15973
15974pub struct SecureMemEventStream {
15975 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
15976}
15977
15978impl std::marker::Unpin for SecureMemEventStream {}
15979
15980impl futures::stream::FusedStream for SecureMemEventStream {
15981 fn is_terminated(&self) -> bool {
15982 self.event_receiver.is_terminated()
15983 }
15984}
15985
15986impl futures::Stream for SecureMemEventStream {
15987 type Item = Result<SecureMemEvent, fidl::Error>;
15988
15989 fn poll_next(
15990 mut self: std::pin::Pin<&mut Self>,
15991 cx: &mut std::task::Context<'_>,
15992 ) -> std::task::Poll<Option<Self::Item>> {
15993 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
15994 &mut self.event_receiver,
15995 cx
15996 )?) {
15997 Some(buf) => std::task::Poll::Ready(Some(SecureMemEvent::decode(buf))),
15998 None => std::task::Poll::Ready(None),
15999 }
16000 }
16001}
16002
16003#[derive(Debug)]
16004pub enum SecureMemEvent {
16005 #[non_exhaustive]
16006 _UnknownEvent {
16007 /// Ordinal of the event that was sent.
16008 ordinal: u64,
16009 },
16010}
16011
16012impl SecureMemEvent {
16013 /// Decodes a message buffer as a [`SecureMemEvent`].
16014 fn decode(
16015 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
16016 ) -> Result<SecureMemEvent, fidl::Error> {
16017 let (bytes, _handles) = buf.split_mut();
16018 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
16019 debug_assert_eq!(tx_header.tx_id, 0);
16020 match tx_header.ordinal {
16021 _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
16022 Ok(SecureMemEvent::_UnknownEvent { ordinal: tx_header.ordinal })
16023 }
16024 _ => Err(fidl::Error::UnknownOrdinal {
16025 ordinal: tx_header.ordinal,
16026 protocol_name: <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
16027 }),
16028 }
16029 }
16030}
16031
16032/// A Stream of incoming requests for fuchsia.sysmem2/SecureMem.
16033pub struct SecureMemRequestStream {
16034 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
16035 is_terminated: bool,
16036}
16037
16038impl std::marker::Unpin for SecureMemRequestStream {}
16039
16040impl futures::stream::FusedStream for SecureMemRequestStream {
16041 fn is_terminated(&self) -> bool {
16042 self.is_terminated
16043 }
16044}
16045
16046impl fidl::endpoints::RequestStream for SecureMemRequestStream {
16047 type Protocol = SecureMemMarker;
16048 type ControlHandle = SecureMemControlHandle;
16049
16050 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
16051 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
16052 }
16053
16054 fn control_handle(&self) -> Self::ControlHandle {
16055 SecureMemControlHandle { inner: self.inner.clone() }
16056 }
16057
16058 fn into_inner(
16059 self,
16060 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
16061 {
16062 (self.inner, self.is_terminated)
16063 }
16064
16065 fn from_inner(
16066 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
16067 is_terminated: bool,
16068 ) -> Self {
16069 Self { inner, is_terminated }
16070 }
16071}
16072
16073impl futures::Stream for SecureMemRequestStream {
16074 type Item = Result<SecureMemRequest, fidl::Error>;
16075
16076 fn poll_next(
16077 mut self: std::pin::Pin<&mut Self>,
16078 cx: &mut std::task::Context<'_>,
16079 ) -> std::task::Poll<Option<Self::Item>> {
16080 let this = &mut *self;
16081 if this.inner.check_shutdown(cx) {
16082 this.is_terminated = true;
16083 return std::task::Poll::Ready(None);
16084 }
16085 if this.is_terminated {
16086 panic!("polled SecureMemRequestStream after completion");
16087 }
16088 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
16089 |bytes, handles| {
16090 match this.inner.channel().read_etc(cx, bytes, handles) {
16091 std::task::Poll::Ready(Ok(())) => {}
16092 std::task::Poll::Pending => return std::task::Poll::Pending,
16093 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
16094 this.is_terminated = true;
16095 return std::task::Poll::Ready(None);
16096 }
16097 std::task::Poll::Ready(Err(e)) => {
16098 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
16099 e.into(),
16100 ))));
16101 }
16102 }
16103
16104 // A message has been received from the channel
16105 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
16106
16107 std::task::Poll::Ready(Some(match header.ordinal {
16108 0x38716300592073e3 => {
16109 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16110 let mut req = fidl::new_empty!(
16111 fidl::encoding::EmptyPayload,
16112 fidl::encoding::DefaultFuchsiaResourceDialect
16113 );
16114 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
16115 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16116 Ok(SecureMemRequest::GetPhysicalSecureHeaps {
16117 responder: SecureMemGetPhysicalSecureHeapsResponder {
16118 control_handle: std::mem::ManuallyDrop::new(control_handle),
16119 tx_id: header.tx_id,
16120 },
16121 })
16122 }
16123 0x1190847f99952834 => {
16124 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16125 let mut req = fidl::new_empty!(
16126 fidl::encoding::EmptyPayload,
16127 fidl::encoding::DefaultFuchsiaResourceDialect
16128 );
16129 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
16130 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16131 Ok(SecureMemRequest::GetDynamicSecureHeaps {
16132 responder: SecureMemGetDynamicSecureHeapsResponder {
16133 control_handle: std::mem::ManuallyDrop::new(control_handle),
16134 tx_id: header.tx_id,
16135 },
16136 })
16137 }
16138 0xc6f06889009c7bc => {
16139 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16140 let mut req = fidl::new_empty!(
16141 SecureMemGetPhysicalSecureHeapPropertiesRequest,
16142 fidl::encoding::DefaultFuchsiaResourceDialect
16143 );
16144 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemGetPhysicalSecureHeapPropertiesRequest>(&header, _body_bytes, handles, &mut req)?;
16145 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16146 Ok(SecureMemRequest::GetPhysicalSecureHeapProperties {
16147 payload: req,
16148 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder {
16149 control_handle: std::mem::ManuallyDrop::new(control_handle),
16150 tx_id: header.tx_id,
16151 },
16152 })
16153 }
16154 0x35f695b9b6c7217a => {
16155 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16156 let mut req = fidl::new_empty!(
16157 SecureMemAddSecureHeapPhysicalRangeRequest,
16158 fidl::encoding::DefaultFuchsiaResourceDialect
16159 );
16160 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemAddSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
16161 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16162 Ok(SecureMemRequest::AddSecureHeapPhysicalRange {
16163 payload: req,
16164 responder: SecureMemAddSecureHeapPhysicalRangeResponder {
16165 control_handle: std::mem::ManuallyDrop::new(control_handle),
16166 tx_id: header.tx_id,
16167 },
16168 })
16169 }
16170 0xeaa58c650264c9e => {
16171 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16172 let mut req = fidl::new_empty!(
16173 SecureMemDeleteSecureHeapPhysicalRangeRequest,
16174 fidl::encoding::DefaultFuchsiaResourceDialect
16175 );
16176 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemDeleteSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
16177 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16178 Ok(SecureMemRequest::DeleteSecureHeapPhysicalRange {
16179 payload: req,
16180 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder {
16181 control_handle: std::mem::ManuallyDrop::new(control_handle),
16182 tx_id: header.tx_id,
16183 },
16184 })
16185 }
16186 0x60b7448aa1187734 => {
16187 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16188 let mut req = fidl::new_empty!(
16189 SecureMemModifySecureHeapPhysicalRangeRequest,
16190 fidl::encoding::DefaultFuchsiaResourceDialect
16191 );
16192 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemModifySecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
16193 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16194 Ok(SecureMemRequest::ModifySecureHeapPhysicalRange {
16195 payload: req,
16196 responder: SecureMemModifySecureHeapPhysicalRangeResponder {
16197 control_handle: std::mem::ManuallyDrop::new(control_handle),
16198 tx_id: header.tx_id,
16199 },
16200 })
16201 }
16202 0x5b25b7901a385ce5 => {
16203 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
16204 let mut req = fidl::new_empty!(
16205 SecureMemZeroSubRangeRequest,
16206 fidl::encoding::DefaultFuchsiaResourceDialect
16207 );
16208 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemZeroSubRangeRequest>(&header, _body_bytes, handles, &mut req)?;
16209 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
16210 Ok(SecureMemRequest::ZeroSubRange {
16211 payload: req,
16212 responder: SecureMemZeroSubRangeResponder {
16213 control_handle: std::mem::ManuallyDrop::new(control_handle),
16214 tx_id: header.tx_id,
16215 },
16216 })
16217 }
16218 _ if header.tx_id == 0
16219 && header
16220 .dynamic_flags()
16221 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
16222 {
16223 Ok(SecureMemRequest::_UnknownMethod {
16224 ordinal: header.ordinal,
16225 control_handle: SecureMemControlHandle { inner: this.inner.clone() },
16226 method_type: fidl::MethodType::OneWay,
16227 })
16228 }
16229 _ if header
16230 .dynamic_flags()
16231 .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
16232 {
16233 this.inner.send_framework_err(
16234 fidl::encoding::FrameworkErr::UnknownMethod,
16235 header.tx_id,
16236 header.ordinal,
16237 header.dynamic_flags(),
16238 (bytes, handles),
16239 )?;
16240 Ok(SecureMemRequest::_UnknownMethod {
16241 ordinal: header.ordinal,
16242 control_handle: SecureMemControlHandle { inner: this.inner.clone() },
16243 method_type: fidl::MethodType::TwoWay,
16244 })
16245 }
16246 _ => Err(fidl::Error::UnknownOrdinal {
16247 ordinal: header.ordinal,
16248 protocol_name:
16249 <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
16250 }),
16251 }))
16252 },
16253 )
16254 }
16255}
16256
16257/// SecureMem
16258///
16259/// The client is sysmem. The server is securemem driver.
16260///
16261/// TEE - Trusted Execution Environment.
16262///
16263/// REE - Rich Execution Environment.
16264///
16265/// Enables sysmem to call the securemem driver to get any secure heaps
16266/// configured via the TEE (or via the securemem driver), and set any physical
16267/// secure heaps configured via sysmem.
16268///
16269/// Presently, dynamically-allocated secure heaps are configured via sysmem, as
16270/// it starts quite early during boot and can successfully reserve contiguous
16271/// physical memory. Presently, fixed-location secure heaps are configured via
16272/// TEE, as the plumbing goes from the bootloader to the TEE. However, this
16273/// protocol intentionally doesn't care which heaps are dynamically-allocated
16274/// and which are fixed-location.
16275#[derive(Debug)]
16276pub enum SecureMemRequest {
16277 /// Gets the physical address and length of any secure heap whose physical
16278 /// range is configured via the TEE.
16279 ///
16280 /// Presently, these will be fixed physical addresses and lengths, with the
16281 /// location plumbed via the TEE.
16282 ///
16283 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
16284 /// when there isn't any special heap-specific per-VMO setup or teardown
16285 /// required.
16286 ///
16287 /// The physical range must be secured/protected by the TEE before the
16288 /// securemem driver responds to this request with success.
16289 ///
16290 /// Sysmem should only call this once. Returning zero heaps is not a
16291 /// failure.
16292 ///
16293 /// Errors:
16294 /// * PROTOCOL_DEVIATION - called more than once.
16295 /// * UNSPECIFIED - generic internal error (such as in communication
16296 /// with TEE which doesn't generate zx_status_t errors).
16297 /// * other errors are allowed; any other errors should be treated the same
16298 /// as UNSPECIFIED.
16299 GetPhysicalSecureHeaps { responder: SecureMemGetPhysicalSecureHeapsResponder },
16300 /// Gets information about any secure heaps whose physical pages are not
16301 /// configured by the TEE, but by sysmem.
16302 ///
16303 /// Sysmem should only call this once. Returning zero heaps is not a
16304 /// failure.
16305 ///
16306 /// Errors:
16307 /// * PROTOCOL_DEVIATION - called more than once.
16308 /// * UNSPECIFIED - generic internal error (such as in communication
16309 /// with TEE which doesn't generate zx_status_t errors).
16310 /// * other errors are allowed; any other errors should be treated the same
16311 /// as UNSPECIFIED.
16312 GetDynamicSecureHeaps { responder: SecureMemGetDynamicSecureHeapsResponder },
16313 /// This request from sysmem to the securemem driver gets the properties of
16314 /// a protected/secure heap.
16315 ///
16316 /// This only handles heaps with a single contiguous physical extent.
16317 ///
16318 /// The heap's entire physical range is indicated in case this request needs
16319 /// some physical space to auto-detect how many ranges are REE-usable. Any
16320 /// temporary HW protection ranges will be deleted before this request
16321 /// completes.
16322 ///
16323 /// Errors:
16324 /// * UNSPECIFIED - generic internal error (such as in communication
16325 /// with TEE which doesn't generate zx_status_t errors).
16326 /// * other errors are allowed; any other errors should be treated the same
16327 /// as UNSPECIFIED.
16328 GetPhysicalSecureHeapProperties {
16329 payload: SecureMemGetPhysicalSecureHeapPropertiesRequest,
16330 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder,
16331 },
16332 /// This request from sysmem to the securemem driver conveys a physical
16333 /// range to add, for a heap whose physical range(s) are set up via
16334 /// sysmem.
16335 ///
16336 /// Only sysmem can call this because only sysmem is handed the client end
16337 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
16338 /// securemem driver is the server end of this protocol.
16339 ///
16340 /// The securemem driver must configure all the covered offsets as protected
16341 /// before responding to this message with success.
16342 ///
16343 /// On failure, the securemem driver must ensure the protected range was not
16344 /// created.
16345 ///
16346 /// Sysmem must only call this up to once if dynamic_protection_ranges
16347 /// false.
16348 ///
16349 /// If dynamic_protection_ranges is true, sysmem can call this multiple
16350 /// times as long as the current number of ranges never exceeds
16351 /// max_protected_range_count.
16352 ///
16353 /// The caller must not attempt to add a range that matches an
16354 /// already-existing range. Added ranges can overlap each other as long as
16355 /// no two ranges match exactly.
16356 ///
16357 /// Errors:
16358 /// * PROTOCOL_DEVIATION - called more than once when
16359 /// !dynamic_protection_ranges. Adding a heap that would cause overall
16360 /// heap count to exceed max_protected_range_count. Unexpected heap, or
16361 /// range that doesn't conform to protected_range_granularity. See log.
16362 /// * UNSPECIFIED - generic internal error (such as in communication
16363 /// with TEE which doesn't generate zx_status_t errors).
16364 /// * other errors are possible, such as from communication failures or
16365 /// server propagation of failures.
16366 AddSecureHeapPhysicalRange {
16367 payload: SecureMemAddSecureHeapPhysicalRangeRequest,
16368 responder: SecureMemAddSecureHeapPhysicalRangeResponder,
16369 },
16370 /// This request from sysmem to the securemem driver conveys a physical
16371 /// range to delete, for a heap whose physical range(s) are set up via
16372 /// sysmem.
16373 ///
16374 /// Only sysmem can call this because only sysmem is handed the client end
16375 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
16376 /// securemem driver is the server end of this protocol.
16377 ///
16378 /// The securemem driver must configure all the covered offsets as not
16379 /// protected before responding to this message with success.
16380 ///
16381 /// On failure, the securemem driver must ensure the protected range was not
16382 /// deleted.
16383 ///
16384 /// Sysmem must not call this if dynamic_protection_ranges false.
16385 ///
16386 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
16387 /// on various ranges that exist at the time of the call.
16388 ///
16389 /// If any portion of the range being deleted is not also covered by another
16390 /// protected range, then any ongoing DMA to any part of the entire range
16391 /// may be interrupted / may fail, potentially in a way that's disruptive to
16392 /// the entire system (bus lockup or similar, depending on device details).
16393 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
16394 /// any portion of the range being deleted, unless the caller has other
16395 /// active ranges covering every block of the range being deleted. Ongoing
16396 /// DMA to/from blocks outside the range being deleted is never impacted by
16397 /// the deletion.
16398 ///
16399 /// Errors:
16400 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
16401 /// Unexpected heap, or range that doesn't conform to
16402 /// protected_range_granularity.
16403 /// * UNSPECIFIED - generic internal error (such as in communication
16404 /// with TEE which doesn't generate zx_status_t errors).
16405 /// * NOT_FOUND - the specified range is not found.
16406 /// * other errors are possible, such as from communication failures or
16407 /// server propagation of failures.
16408 DeleteSecureHeapPhysicalRange {
16409 payload: SecureMemDeleteSecureHeapPhysicalRangeRequest,
16410 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder,
16411 },
16412 /// This request from sysmem to the securemem driver conveys a physical
16413 /// range to modify and its new base and length, for a heap whose physical
16414 /// range(s) are set up via sysmem.
16415 ///
16416 /// Only sysmem can call this because only sysmem is handed the client end
16417 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
16418 /// securemem driver is the server end of this protocol.
16419 ///
16420 /// The securemem driver must configure the range to cover only the new
16421 /// offsets before responding to this message with success.
16422 ///
16423 /// On failure, the securemem driver must ensure the range was not changed.
16424 ///
16425 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
16426 /// must not call this if !is_mod_protected_range_available.
16427 ///
16428 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
16429 /// on various ranges that exist at the time of the call.
16430 ///
16431 /// The range must only be modified at one end or the other, but not both.
16432 /// If the range is getting shorter, and the un-covered blocks are not
16433 /// covered by other active ranges, any ongoing DMA to the entire range
16434 /// that's geting shorter may fail in a way that disrupts the entire system
16435 /// (bus lockup or similar), so the caller must ensure that no DMA is
16436 /// ongoing to any portion of a range that is getting shorter, unless the
16437 /// blocks being un-covered by the modification to this range are all
16438 /// covered by other active ranges, in which case no disruption to ongoing
16439 /// DMA will occur.
16440 ///
16441 /// If a range is modified to become <= zero length, the range is deleted.
16442 ///
16443 /// Errors:
16444 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
16445 /// Unexpected heap, or old_range or new_range that doesn't conform to
16446 /// protected_range_granularity, or old_range and new_range differ in
16447 /// both begin and end (disallowed).
16448 /// * UNSPECIFIED - generic internal error (such as in communication
16449 /// with TEE which doesn't generate zx_status_t errors).
16450 /// * NOT_FOUND - the specified range is not found.
16451 /// * other errors are possible, such as from communication failures or
16452 /// server propagation of failures.
16453 ModifySecureHeapPhysicalRange {
16454 payload: SecureMemModifySecureHeapPhysicalRangeRequest,
16455 responder: SecureMemModifySecureHeapPhysicalRangeResponder,
16456 },
16457 /// Zero a sub-range of a currently-existing physical range added via
16458 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
16459 /// exactly one physical range, and must not overlap with any other
16460 /// physical range.
16461 ///
16462 /// is_covering_range_explicit - When true, the covering range must be one
16463 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
16464 /// possibly modified since. When false, the covering range must not
16465 /// be one of the ranges explicitly created via
16466 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
16467 /// a covering range not created via AddSecureHeapPhysicalRange(). The
16468 /// covering range is typically the entire physical range (or a range
16469 /// which covers even more) of a heap configured by the TEE and whose
16470 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
16471 ///
16472 /// Ongoing DMA is not disrupted by this request.
16473 ///
16474 /// Errors:
16475 /// * PROTOCOL_DEVIATION - called when !dynamic_protection_ranges.
16476 /// Unexpected heap.
16477 /// * UNSPECIFIED - generic internal error (such as in communication
16478 /// with TEE which doesn't generate zx_status_t errors).
16479 /// * other errors are possible, such as from communication failures or
16480 /// server propagation of failures.
16481 ZeroSubRange {
16482 payload: SecureMemZeroSubRangeRequest,
16483 responder: SecureMemZeroSubRangeResponder,
16484 },
16485 /// An interaction was received which does not match any known method.
16486 #[non_exhaustive]
16487 _UnknownMethod {
16488 /// Ordinal of the method that was called.
16489 ordinal: u64,
16490 control_handle: SecureMemControlHandle,
16491 method_type: fidl::MethodType,
16492 },
16493}
16494
16495impl SecureMemRequest {
16496 #[allow(irrefutable_let_patterns)]
16497 pub fn into_get_physical_secure_heaps(
16498 self,
16499 ) -> Option<(SecureMemGetPhysicalSecureHeapsResponder)> {
16500 if let SecureMemRequest::GetPhysicalSecureHeaps { responder } = self {
16501 Some((responder))
16502 } else {
16503 None
16504 }
16505 }
16506
16507 #[allow(irrefutable_let_patterns)]
16508 pub fn into_get_dynamic_secure_heaps(
16509 self,
16510 ) -> Option<(SecureMemGetDynamicSecureHeapsResponder)> {
16511 if let SecureMemRequest::GetDynamicSecureHeaps { responder } = self {
16512 Some((responder))
16513 } else {
16514 None
16515 }
16516 }
16517
16518 #[allow(irrefutable_let_patterns)]
16519 pub fn into_get_physical_secure_heap_properties(
16520 self,
16521 ) -> Option<(
16522 SecureMemGetPhysicalSecureHeapPropertiesRequest,
16523 SecureMemGetPhysicalSecureHeapPropertiesResponder,
16524 )> {
16525 if let SecureMemRequest::GetPhysicalSecureHeapProperties { payload, responder } = self {
16526 Some((payload, responder))
16527 } else {
16528 None
16529 }
16530 }
16531
16532 #[allow(irrefutable_let_patterns)]
16533 pub fn into_add_secure_heap_physical_range(
16534 self,
16535 ) -> Option<(
16536 SecureMemAddSecureHeapPhysicalRangeRequest,
16537 SecureMemAddSecureHeapPhysicalRangeResponder,
16538 )> {
16539 if let SecureMemRequest::AddSecureHeapPhysicalRange { payload, responder } = self {
16540 Some((payload, responder))
16541 } else {
16542 None
16543 }
16544 }
16545
16546 #[allow(irrefutable_let_patterns)]
16547 pub fn into_delete_secure_heap_physical_range(
16548 self,
16549 ) -> Option<(
16550 SecureMemDeleteSecureHeapPhysicalRangeRequest,
16551 SecureMemDeleteSecureHeapPhysicalRangeResponder,
16552 )> {
16553 if let SecureMemRequest::DeleteSecureHeapPhysicalRange { payload, responder } = self {
16554 Some((payload, responder))
16555 } else {
16556 None
16557 }
16558 }
16559
16560 #[allow(irrefutable_let_patterns)]
16561 pub fn into_modify_secure_heap_physical_range(
16562 self,
16563 ) -> Option<(
16564 SecureMemModifySecureHeapPhysicalRangeRequest,
16565 SecureMemModifySecureHeapPhysicalRangeResponder,
16566 )> {
16567 if let SecureMemRequest::ModifySecureHeapPhysicalRange { payload, responder } = self {
16568 Some((payload, responder))
16569 } else {
16570 None
16571 }
16572 }
16573
16574 #[allow(irrefutable_let_patterns)]
16575 pub fn into_zero_sub_range(
16576 self,
16577 ) -> Option<(SecureMemZeroSubRangeRequest, SecureMemZeroSubRangeResponder)> {
16578 if let SecureMemRequest::ZeroSubRange { payload, responder } = self {
16579 Some((payload, responder))
16580 } else {
16581 None
16582 }
16583 }
16584
16585 /// Name of the method defined in FIDL
16586 pub fn method_name(&self) -> &'static str {
16587 match *self {
16588 SecureMemRequest::GetPhysicalSecureHeaps { .. } => "get_physical_secure_heaps",
16589 SecureMemRequest::GetDynamicSecureHeaps { .. } => "get_dynamic_secure_heaps",
16590 SecureMemRequest::GetPhysicalSecureHeapProperties { .. } => {
16591 "get_physical_secure_heap_properties"
16592 }
16593 SecureMemRequest::AddSecureHeapPhysicalRange { .. } => "add_secure_heap_physical_range",
16594 SecureMemRequest::DeleteSecureHeapPhysicalRange { .. } => {
16595 "delete_secure_heap_physical_range"
16596 }
16597 SecureMemRequest::ModifySecureHeapPhysicalRange { .. } => {
16598 "modify_secure_heap_physical_range"
16599 }
16600 SecureMemRequest::ZeroSubRange { .. } => "zero_sub_range",
16601 SecureMemRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
16602 "unknown one-way method"
16603 }
16604 SecureMemRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
16605 "unknown two-way method"
16606 }
16607 }
16608 }
16609}
16610
16611#[derive(Debug, Clone)]
16612pub struct SecureMemControlHandle {
16613 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
16614}
16615
16616impl fidl::endpoints::ControlHandle for SecureMemControlHandle {
16617 fn shutdown(&self) {
16618 self.inner.shutdown()
16619 }
16620
16621 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
16622 self.inner.shutdown_with_epitaph(status)
16623 }
16624
16625 fn is_closed(&self) -> bool {
16626 self.inner.channel().is_closed()
16627 }
16628 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
16629 self.inner.channel().on_closed()
16630 }
16631
16632 #[cfg(target_os = "fuchsia")]
16633 fn signal_peer(
16634 &self,
16635 clear_mask: zx::Signals,
16636 set_mask: zx::Signals,
16637 ) -> Result<(), zx_status::Status> {
16638 use fidl::Peered;
16639 self.inner.channel().signal_peer(clear_mask, set_mask)
16640 }
16641}
16642
16643impl SecureMemControlHandle {}
16644
16645#[must_use = "FIDL methods require a response to be sent"]
16646#[derive(Debug)]
16647pub struct SecureMemGetPhysicalSecureHeapsResponder {
16648 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
16649 tx_id: u32,
16650}
16651
16652/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
16653/// if the responder is dropped without sending a response, so that the client
16654/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
16655impl std::ops::Drop for SecureMemGetPhysicalSecureHeapsResponder {
16656 fn drop(&mut self) {
16657 self.control_handle.shutdown();
16658 // Safety: drops once, never accessed again
16659 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16660 }
16661}
16662
16663impl fidl::endpoints::Responder for SecureMemGetPhysicalSecureHeapsResponder {
16664 type ControlHandle = SecureMemControlHandle;
16665
16666 fn control_handle(&self) -> &SecureMemControlHandle {
16667 &self.control_handle
16668 }
16669
16670 fn drop_without_shutdown(mut self) {
16671 // Safety: drops once, never accessed again due to mem::forget
16672 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16673 // Prevent Drop from running (which would shut down the channel)
16674 std::mem::forget(self);
16675 }
16676}
16677
16678impl SecureMemGetPhysicalSecureHeapsResponder {
16679 /// Sends a response to the FIDL transaction.
16680 ///
16681 /// Sets the channel to shutdown if an error occurs.
16682 pub fn send(
16683 self,
16684 mut result: Result<&SecureMemGetPhysicalSecureHeapsResponse, Error>,
16685 ) -> Result<(), fidl::Error> {
16686 let _result = self.send_raw(result);
16687 if _result.is_err() {
16688 self.control_handle.shutdown();
16689 }
16690 self.drop_without_shutdown();
16691 _result
16692 }
16693
16694 /// Similar to "send" but does not shutdown the channel if an error occurs.
16695 pub fn send_no_shutdown_on_err(
16696 self,
16697 mut result: Result<&SecureMemGetPhysicalSecureHeapsResponse, Error>,
16698 ) -> Result<(), fidl::Error> {
16699 let _result = self.send_raw(result);
16700 self.drop_without_shutdown();
16701 _result
16702 }
16703
16704 fn send_raw(
16705 &self,
16706 mut result: Result<&SecureMemGetPhysicalSecureHeapsResponse, Error>,
16707 ) -> Result<(), fidl::Error> {
16708 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
16709 SecureMemGetPhysicalSecureHeapsResponse,
16710 Error,
16711 >>(
16712 fidl::encoding::FlexibleResult::new(result),
16713 self.tx_id,
16714 0x38716300592073e3,
16715 fidl::encoding::DynamicFlags::FLEXIBLE,
16716 )
16717 }
16718}
16719
16720#[must_use = "FIDL methods require a response to be sent"]
16721#[derive(Debug)]
16722pub struct SecureMemGetDynamicSecureHeapsResponder {
16723 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
16724 tx_id: u32,
16725}
16726
16727/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
16728/// if the responder is dropped without sending a response, so that the client
16729/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
16730impl std::ops::Drop for SecureMemGetDynamicSecureHeapsResponder {
16731 fn drop(&mut self) {
16732 self.control_handle.shutdown();
16733 // Safety: drops once, never accessed again
16734 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16735 }
16736}
16737
16738impl fidl::endpoints::Responder for SecureMemGetDynamicSecureHeapsResponder {
16739 type ControlHandle = SecureMemControlHandle;
16740
16741 fn control_handle(&self) -> &SecureMemControlHandle {
16742 &self.control_handle
16743 }
16744
16745 fn drop_without_shutdown(mut self) {
16746 // Safety: drops once, never accessed again due to mem::forget
16747 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16748 // Prevent Drop from running (which would shut down the channel)
16749 std::mem::forget(self);
16750 }
16751}
16752
16753impl SecureMemGetDynamicSecureHeapsResponder {
16754 /// Sends a response to the FIDL transaction.
16755 ///
16756 /// Sets the channel to shutdown if an error occurs.
16757 pub fn send(
16758 self,
16759 mut result: Result<&SecureMemGetDynamicSecureHeapsResponse, Error>,
16760 ) -> Result<(), fidl::Error> {
16761 let _result = self.send_raw(result);
16762 if _result.is_err() {
16763 self.control_handle.shutdown();
16764 }
16765 self.drop_without_shutdown();
16766 _result
16767 }
16768
16769 /// Similar to "send" but does not shutdown the channel if an error occurs.
16770 pub fn send_no_shutdown_on_err(
16771 self,
16772 mut result: Result<&SecureMemGetDynamicSecureHeapsResponse, Error>,
16773 ) -> Result<(), fidl::Error> {
16774 let _result = self.send_raw(result);
16775 self.drop_without_shutdown();
16776 _result
16777 }
16778
16779 fn send_raw(
16780 &self,
16781 mut result: Result<&SecureMemGetDynamicSecureHeapsResponse, Error>,
16782 ) -> Result<(), fidl::Error> {
16783 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
16784 SecureMemGetDynamicSecureHeapsResponse,
16785 Error,
16786 >>(
16787 fidl::encoding::FlexibleResult::new(result),
16788 self.tx_id,
16789 0x1190847f99952834,
16790 fidl::encoding::DynamicFlags::FLEXIBLE,
16791 )
16792 }
16793}
16794
16795#[must_use = "FIDL methods require a response to be sent"]
16796#[derive(Debug)]
16797pub struct SecureMemGetPhysicalSecureHeapPropertiesResponder {
16798 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
16799 tx_id: u32,
16800}
16801
16802/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
16803/// if the responder is dropped without sending a response, so that the client
16804/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
16805impl std::ops::Drop for SecureMemGetPhysicalSecureHeapPropertiesResponder {
16806 fn drop(&mut self) {
16807 self.control_handle.shutdown();
16808 // Safety: drops once, never accessed again
16809 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16810 }
16811}
16812
16813impl fidl::endpoints::Responder for SecureMemGetPhysicalSecureHeapPropertiesResponder {
16814 type ControlHandle = SecureMemControlHandle;
16815
16816 fn control_handle(&self) -> &SecureMemControlHandle {
16817 &self.control_handle
16818 }
16819
16820 fn drop_without_shutdown(mut self) {
16821 // Safety: drops once, never accessed again due to mem::forget
16822 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16823 // Prevent Drop from running (which would shut down the channel)
16824 std::mem::forget(self);
16825 }
16826}
16827
16828impl SecureMemGetPhysicalSecureHeapPropertiesResponder {
16829 /// Sends a response to the FIDL transaction.
16830 ///
16831 /// Sets the channel to shutdown if an error occurs.
16832 pub fn send(
16833 self,
16834 mut result: Result<&SecureMemGetPhysicalSecureHeapPropertiesResponse, Error>,
16835 ) -> Result<(), fidl::Error> {
16836 let _result = self.send_raw(result);
16837 if _result.is_err() {
16838 self.control_handle.shutdown();
16839 }
16840 self.drop_without_shutdown();
16841 _result
16842 }
16843
16844 /// Similar to "send" but does not shutdown the channel if an error occurs.
16845 pub fn send_no_shutdown_on_err(
16846 self,
16847 mut result: Result<&SecureMemGetPhysicalSecureHeapPropertiesResponse, Error>,
16848 ) -> Result<(), fidl::Error> {
16849 let _result = self.send_raw(result);
16850 self.drop_without_shutdown();
16851 _result
16852 }
16853
16854 fn send_raw(
16855 &self,
16856 mut result: Result<&SecureMemGetPhysicalSecureHeapPropertiesResponse, Error>,
16857 ) -> Result<(), fidl::Error> {
16858 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
16859 SecureMemGetPhysicalSecureHeapPropertiesResponse,
16860 Error,
16861 >>(
16862 fidl::encoding::FlexibleResult::new(result),
16863 self.tx_id,
16864 0xc6f06889009c7bc,
16865 fidl::encoding::DynamicFlags::FLEXIBLE,
16866 )
16867 }
16868}
16869
16870#[must_use = "FIDL methods require a response to be sent"]
16871#[derive(Debug)]
16872pub struct SecureMemAddSecureHeapPhysicalRangeResponder {
16873 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
16874 tx_id: u32,
16875}
16876
16877/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
16878/// if the responder is dropped without sending a response, so that the client
16879/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
16880impl std::ops::Drop for SecureMemAddSecureHeapPhysicalRangeResponder {
16881 fn drop(&mut self) {
16882 self.control_handle.shutdown();
16883 // Safety: drops once, never accessed again
16884 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16885 }
16886}
16887
16888impl fidl::endpoints::Responder for SecureMemAddSecureHeapPhysicalRangeResponder {
16889 type ControlHandle = SecureMemControlHandle;
16890
16891 fn control_handle(&self) -> &SecureMemControlHandle {
16892 &self.control_handle
16893 }
16894
16895 fn drop_without_shutdown(mut self) {
16896 // Safety: drops once, never accessed again due to mem::forget
16897 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16898 // Prevent Drop from running (which would shut down the channel)
16899 std::mem::forget(self);
16900 }
16901}
16902
16903impl SecureMemAddSecureHeapPhysicalRangeResponder {
16904 /// Sends a response to the FIDL transaction.
16905 ///
16906 /// Sets the channel to shutdown if an error occurs.
16907 pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
16908 let _result = self.send_raw(result);
16909 if _result.is_err() {
16910 self.control_handle.shutdown();
16911 }
16912 self.drop_without_shutdown();
16913 _result
16914 }
16915
16916 /// Similar to "send" but does not shutdown the channel if an error occurs.
16917 pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
16918 let _result = self.send_raw(result);
16919 self.drop_without_shutdown();
16920 _result
16921 }
16922
16923 fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
16924 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
16925 fidl::encoding::EmptyStruct,
16926 Error,
16927 >>(
16928 fidl::encoding::FlexibleResult::new(result),
16929 self.tx_id,
16930 0x35f695b9b6c7217a,
16931 fidl::encoding::DynamicFlags::FLEXIBLE,
16932 )
16933 }
16934}
16935
16936#[must_use = "FIDL methods require a response to be sent"]
16937#[derive(Debug)]
16938pub struct SecureMemDeleteSecureHeapPhysicalRangeResponder {
16939 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
16940 tx_id: u32,
16941}
16942
16943/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
16944/// if the responder is dropped without sending a response, so that the client
16945/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
16946impl std::ops::Drop for SecureMemDeleteSecureHeapPhysicalRangeResponder {
16947 fn drop(&mut self) {
16948 self.control_handle.shutdown();
16949 // Safety: drops once, never accessed again
16950 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16951 }
16952}
16953
16954impl fidl::endpoints::Responder for SecureMemDeleteSecureHeapPhysicalRangeResponder {
16955 type ControlHandle = SecureMemControlHandle;
16956
16957 fn control_handle(&self) -> &SecureMemControlHandle {
16958 &self.control_handle
16959 }
16960
16961 fn drop_without_shutdown(mut self) {
16962 // Safety: drops once, never accessed again due to mem::forget
16963 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
16964 // Prevent Drop from running (which would shut down the channel)
16965 std::mem::forget(self);
16966 }
16967}
16968
16969impl SecureMemDeleteSecureHeapPhysicalRangeResponder {
16970 /// Sends a response to the FIDL transaction.
16971 ///
16972 /// Sets the channel to shutdown if an error occurs.
16973 pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
16974 let _result = self.send_raw(result);
16975 if _result.is_err() {
16976 self.control_handle.shutdown();
16977 }
16978 self.drop_without_shutdown();
16979 _result
16980 }
16981
16982 /// Similar to "send" but does not shutdown the channel if an error occurs.
16983 pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
16984 let _result = self.send_raw(result);
16985 self.drop_without_shutdown();
16986 _result
16987 }
16988
16989 fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
16990 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
16991 fidl::encoding::EmptyStruct,
16992 Error,
16993 >>(
16994 fidl::encoding::FlexibleResult::new(result),
16995 self.tx_id,
16996 0xeaa58c650264c9e,
16997 fidl::encoding::DynamicFlags::FLEXIBLE,
16998 )
16999 }
17000}
17001
17002#[must_use = "FIDL methods require a response to be sent"]
17003#[derive(Debug)]
17004pub struct SecureMemModifySecureHeapPhysicalRangeResponder {
17005 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
17006 tx_id: u32,
17007}
17008
17009/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
17010/// if the responder is dropped without sending a response, so that the client
17011/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
17012impl std::ops::Drop for SecureMemModifySecureHeapPhysicalRangeResponder {
17013 fn drop(&mut self) {
17014 self.control_handle.shutdown();
17015 // Safety: drops once, never accessed again
17016 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
17017 }
17018}
17019
17020impl fidl::endpoints::Responder for SecureMemModifySecureHeapPhysicalRangeResponder {
17021 type ControlHandle = SecureMemControlHandle;
17022
17023 fn control_handle(&self) -> &SecureMemControlHandle {
17024 &self.control_handle
17025 }
17026
17027 fn drop_without_shutdown(mut self) {
17028 // Safety: drops once, never accessed again due to mem::forget
17029 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
17030 // Prevent Drop from running (which would shut down the channel)
17031 std::mem::forget(self);
17032 }
17033}
17034
17035impl SecureMemModifySecureHeapPhysicalRangeResponder {
17036 /// Sends a response to the FIDL transaction.
17037 ///
17038 /// Sets the channel to shutdown if an error occurs.
17039 pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17040 let _result = self.send_raw(result);
17041 if _result.is_err() {
17042 self.control_handle.shutdown();
17043 }
17044 self.drop_without_shutdown();
17045 _result
17046 }
17047
17048 /// Similar to "send" but does not shutdown the channel if an error occurs.
17049 pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17050 let _result = self.send_raw(result);
17051 self.drop_without_shutdown();
17052 _result
17053 }
17054
17055 fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17056 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
17057 fidl::encoding::EmptyStruct,
17058 Error,
17059 >>(
17060 fidl::encoding::FlexibleResult::new(result),
17061 self.tx_id,
17062 0x60b7448aa1187734,
17063 fidl::encoding::DynamicFlags::FLEXIBLE,
17064 )
17065 }
17066}
17067
17068#[must_use = "FIDL methods require a response to be sent"]
17069#[derive(Debug)]
17070pub struct SecureMemZeroSubRangeResponder {
17071 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
17072 tx_id: u32,
17073}
17074
17075/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
17076/// if the responder is dropped without sending a response, so that the client
17077/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
17078impl std::ops::Drop for SecureMemZeroSubRangeResponder {
17079 fn drop(&mut self) {
17080 self.control_handle.shutdown();
17081 // Safety: drops once, never accessed again
17082 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
17083 }
17084}
17085
17086impl fidl::endpoints::Responder for SecureMemZeroSubRangeResponder {
17087 type ControlHandle = SecureMemControlHandle;
17088
17089 fn control_handle(&self) -> &SecureMemControlHandle {
17090 &self.control_handle
17091 }
17092
17093 fn drop_without_shutdown(mut self) {
17094 // Safety: drops once, never accessed again due to mem::forget
17095 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
17096 // Prevent Drop from running (which would shut down the channel)
17097 std::mem::forget(self);
17098 }
17099}
17100
17101impl SecureMemZeroSubRangeResponder {
17102 /// Sends a response to the FIDL transaction.
17103 ///
17104 /// Sets the channel to shutdown if an error occurs.
17105 pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17106 let _result = self.send_raw(result);
17107 if _result.is_err() {
17108 self.control_handle.shutdown();
17109 }
17110 self.drop_without_shutdown();
17111 _result
17112 }
17113
17114 /// Similar to "send" but does not shutdown the channel if an error occurs.
17115 pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17116 let _result = self.send_raw(result);
17117 self.drop_without_shutdown();
17118 _result
17119 }
17120
17121 fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
17122 self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
17123 fidl::encoding::EmptyStruct,
17124 Error,
17125 >>(
17126 fidl::encoding::FlexibleResult::new(result),
17127 self.tx_id,
17128 0x5b25b7901a385ce5,
17129 fidl::encoding::DynamicFlags::FLEXIBLE,
17130 )
17131 }
17132}
17133
17134mod internal {
17135 use super::*;
17136
17137 impl AllocatorAllocateNonSharedCollectionRequest {
17138 #[inline(always)]
17139 fn max_ordinal_present(&self) -> u64 {
17140 if let Some(_) = self.collection_request {
17141 return 1;
17142 }
17143 0
17144 }
17145 }
17146
17147 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateNonSharedCollectionRequest {
17148 type Borrowed<'a> = &'a mut Self;
17149 fn take_or_borrow<'a>(
17150 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
17151 ) -> Self::Borrowed<'a> {
17152 value
17153 }
17154 }
17155
17156 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateNonSharedCollectionRequest {
17157 type Owned = Self;
17158
17159 #[inline(always)]
17160 fn inline_align(_context: fidl::encoding::Context) -> usize {
17161 8
17162 }
17163
17164 #[inline(always)]
17165 fn inline_size(_context: fidl::encoding::Context) -> usize {
17166 16
17167 }
17168 }
17169
17170 unsafe impl
17171 fidl::encoding::Encode<
17172 AllocatorAllocateNonSharedCollectionRequest,
17173 fidl::encoding::DefaultFuchsiaResourceDialect,
17174 > for &mut AllocatorAllocateNonSharedCollectionRequest
17175 {
17176 unsafe fn encode(
17177 self,
17178 encoder: &mut fidl::encoding::Encoder<
17179 '_,
17180 fidl::encoding::DefaultFuchsiaResourceDialect,
17181 >,
17182 offset: usize,
17183 mut depth: fidl::encoding::Depth,
17184 ) -> fidl::Result<()> {
17185 encoder.debug_check_bounds::<AllocatorAllocateNonSharedCollectionRequest>(offset);
17186 // Vector header
17187 let max_ordinal: u64 = self.max_ordinal_present();
17188 encoder.write_num(max_ordinal, offset);
17189 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
17190 // Calling encoder.out_of_line_offset(0) is not allowed.
17191 if max_ordinal == 0 {
17192 return Ok(());
17193 }
17194 depth.increment()?;
17195 let envelope_size = 8;
17196 let bytes_len = max_ordinal as usize * envelope_size;
17197 #[allow(unused_variables)]
17198 let offset = encoder.out_of_line_offset(bytes_len);
17199 let mut _prev_end_offset: usize = 0;
17200 if 1 > max_ordinal {
17201 return Ok(());
17202 }
17203
17204 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17205 // are envelope_size bytes.
17206 let cur_offset: usize = (1 - 1) * envelope_size;
17207
17208 // Zero reserved fields.
17209 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17210
17211 // Safety:
17212 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17213 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17214 // envelope_size bytes, there is always sufficient room.
17215 fidl::encoding::encode_in_envelope_optional::<fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>, fidl::encoding::DefaultFuchsiaResourceDialect>(
17216 self.collection_request.as_mut().map(<fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow),
17217 encoder, offset + cur_offset, depth
17218 )?;
17219
17220 _prev_end_offset = cur_offset + envelope_size;
17221
17222 Ok(())
17223 }
17224 }
17225
17226 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
17227 for AllocatorAllocateNonSharedCollectionRequest
17228 {
17229 #[inline(always)]
17230 fn new_empty() -> Self {
17231 Self::default()
17232 }
17233
17234 unsafe fn decode(
17235 &mut self,
17236 decoder: &mut fidl::encoding::Decoder<
17237 '_,
17238 fidl::encoding::DefaultFuchsiaResourceDialect,
17239 >,
17240 offset: usize,
17241 mut depth: fidl::encoding::Depth,
17242 ) -> fidl::Result<()> {
17243 decoder.debug_check_bounds::<Self>(offset);
17244 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
17245 None => return Err(fidl::Error::NotNullable),
17246 Some(len) => len,
17247 };
17248 // Calling decoder.out_of_line_offset(0) is not allowed.
17249 if len == 0 {
17250 return Ok(());
17251 };
17252 depth.increment()?;
17253 let envelope_size = 8;
17254 let bytes_len = len * envelope_size;
17255 let offset = decoder.out_of_line_offset(bytes_len)?;
17256 // Decode the envelope for each type.
17257 let mut _next_ordinal_to_read = 0;
17258 let mut next_offset = offset;
17259 let end_offset = offset + bytes_len;
17260 _next_ordinal_to_read += 1;
17261 if next_offset >= end_offset {
17262 return Ok(());
17263 }
17264
17265 // Decode unknown envelopes for gaps in ordinals.
17266 while _next_ordinal_to_read < 1 {
17267 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17268 _next_ordinal_to_read += 1;
17269 next_offset += envelope_size;
17270 }
17271
17272 let next_out_of_line = decoder.next_out_of_line();
17273 let handles_before = decoder.remaining_handles();
17274 if let Some((inlined, num_bytes, num_handles)) =
17275 fidl::encoding::decode_envelope_header(decoder, next_offset)?
17276 {
17277 let member_inline_size = <fidl::encoding::Endpoint<
17278 fidl::endpoints::ServerEnd<BufferCollectionMarker>,
17279 > as fidl::encoding::TypeMarker>::inline_size(
17280 decoder.context
17281 );
17282 if inlined != (member_inline_size <= 4) {
17283 return Err(fidl::Error::InvalidInlineBitInEnvelope);
17284 }
17285 let inner_offset;
17286 let mut inner_depth = depth.clone();
17287 if inlined {
17288 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
17289 inner_offset = next_offset;
17290 } else {
17291 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
17292 inner_depth.increment()?;
17293 }
17294 let val_ref = self.collection_request.get_or_insert_with(|| {
17295 fidl::new_empty!(
17296 fidl::encoding::Endpoint<
17297 fidl::endpoints::ServerEnd<BufferCollectionMarker>,
17298 >,
17299 fidl::encoding::DefaultFuchsiaResourceDialect
17300 )
17301 });
17302 fidl::decode!(
17303 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
17304 fidl::encoding::DefaultFuchsiaResourceDialect,
17305 val_ref,
17306 decoder,
17307 inner_offset,
17308 inner_depth
17309 )?;
17310 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
17311 {
17312 return Err(fidl::Error::InvalidNumBytesInEnvelope);
17313 }
17314 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
17315 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
17316 }
17317 }
17318
17319 next_offset += envelope_size;
17320
17321 // Decode the remaining unknown envelopes.
17322 while next_offset < end_offset {
17323 _next_ordinal_to_read += 1;
17324 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17325 next_offset += envelope_size;
17326 }
17327
17328 Ok(())
17329 }
17330 }
17331
17332 impl AllocatorAllocateSharedCollectionRequest {
17333 #[inline(always)]
17334 fn max_ordinal_present(&self) -> u64 {
17335 if let Some(_) = self.token_request {
17336 return 1;
17337 }
17338 0
17339 }
17340 }
17341
17342 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateSharedCollectionRequest {
17343 type Borrowed<'a> = &'a mut Self;
17344 fn take_or_borrow<'a>(
17345 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
17346 ) -> Self::Borrowed<'a> {
17347 value
17348 }
17349 }
17350
17351 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateSharedCollectionRequest {
17352 type Owned = Self;
17353
17354 #[inline(always)]
17355 fn inline_align(_context: fidl::encoding::Context) -> usize {
17356 8
17357 }
17358
17359 #[inline(always)]
17360 fn inline_size(_context: fidl::encoding::Context) -> usize {
17361 16
17362 }
17363 }
17364
17365 unsafe impl
17366 fidl::encoding::Encode<
17367 AllocatorAllocateSharedCollectionRequest,
17368 fidl::encoding::DefaultFuchsiaResourceDialect,
17369 > for &mut AllocatorAllocateSharedCollectionRequest
17370 {
17371 unsafe fn encode(
17372 self,
17373 encoder: &mut fidl::encoding::Encoder<
17374 '_,
17375 fidl::encoding::DefaultFuchsiaResourceDialect,
17376 >,
17377 offset: usize,
17378 mut depth: fidl::encoding::Depth,
17379 ) -> fidl::Result<()> {
17380 encoder.debug_check_bounds::<AllocatorAllocateSharedCollectionRequest>(offset);
17381 // Vector header
17382 let max_ordinal: u64 = self.max_ordinal_present();
17383 encoder.write_num(max_ordinal, offset);
17384 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
17385 // Calling encoder.out_of_line_offset(0) is not allowed.
17386 if max_ordinal == 0 {
17387 return Ok(());
17388 }
17389 depth.increment()?;
17390 let envelope_size = 8;
17391 let bytes_len = max_ordinal as usize * envelope_size;
17392 #[allow(unused_variables)]
17393 let offset = encoder.out_of_line_offset(bytes_len);
17394 let mut _prev_end_offset: usize = 0;
17395 if 1 > max_ordinal {
17396 return Ok(());
17397 }
17398
17399 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17400 // are envelope_size bytes.
17401 let cur_offset: usize = (1 - 1) * envelope_size;
17402
17403 // Zero reserved fields.
17404 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17405
17406 // Safety:
17407 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17408 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17409 // envelope_size bytes, there is always sufficient room.
17410 fidl::encoding::encode_in_envelope_optional::<
17411 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
17412 fidl::encoding::DefaultFuchsiaResourceDialect,
17413 >(
17414 self.token_request.as_mut().map(
17415 <fidl::encoding::Endpoint<
17416 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
17417 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
17418 ),
17419 encoder,
17420 offset + cur_offset,
17421 depth,
17422 )?;
17423
17424 _prev_end_offset = cur_offset + envelope_size;
17425
17426 Ok(())
17427 }
17428 }
17429
17430 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
17431 for AllocatorAllocateSharedCollectionRequest
17432 {
17433 #[inline(always)]
17434 fn new_empty() -> Self {
17435 Self::default()
17436 }
17437
17438 unsafe fn decode(
17439 &mut self,
17440 decoder: &mut fidl::encoding::Decoder<
17441 '_,
17442 fidl::encoding::DefaultFuchsiaResourceDialect,
17443 >,
17444 offset: usize,
17445 mut depth: fidl::encoding::Depth,
17446 ) -> fidl::Result<()> {
17447 decoder.debug_check_bounds::<Self>(offset);
17448 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
17449 None => return Err(fidl::Error::NotNullable),
17450 Some(len) => len,
17451 };
17452 // Calling decoder.out_of_line_offset(0) is not allowed.
17453 if len == 0 {
17454 return Ok(());
17455 };
17456 depth.increment()?;
17457 let envelope_size = 8;
17458 let bytes_len = len * envelope_size;
17459 let offset = decoder.out_of_line_offset(bytes_len)?;
17460 // Decode the envelope for each type.
17461 let mut _next_ordinal_to_read = 0;
17462 let mut next_offset = offset;
17463 let end_offset = offset + bytes_len;
17464 _next_ordinal_to_read += 1;
17465 if next_offset >= end_offset {
17466 return Ok(());
17467 }
17468
17469 // Decode unknown envelopes for gaps in ordinals.
17470 while _next_ordinal_to_read < 1 {
17471 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17472 _next_ordinal_to_read += 1;
17473 next_offset += envelope_size;
17474 }
17475
17476 let next_out_of_line = decoder.next_out_of_line();
17477 let handles_before = decoder.remaining_handles();
17478 if let Some((inlined, num_bytes, num_handles)) =
17479 fidl::encoding::decode_envelope_header(decoder, next_offset)?
17480 {
17481 let member_inline_size = <fidl::encoding::Endpoint<
17482 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
17483 > as fidl::encoding::TypeMarker>::inline_size(
17484 decoder.context
17485 );
17486 if inlined != (member_inline_size <= 4) {
17487 return Err(fidl::Error::InvalidInlineBitInEnvelope);
17488 }
17489 let inner_offset;
17490 let mut inner_depth = depth.clone();
17491 if inlined {
17492 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
17493 inner_offset = next_offset;
17494 } else {
17495 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
17496 inner_depth.increment()?;
17497 }
17498 let val_ref = self.token_request.get_or_insert_with(|| {
17499 fidl::new_empty!(
17500 fidl::encoding::Endpoint<
17501 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
17502 >,
17503 fidl::encoding::DefaultFuchsiaResourceDialect
17504 )
17505 });
17506 fidl::decode!(
17507 fidl::encoding::Endpoint<
17508 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
17509 >,
17510 fidl::encoding::DefaultFuchsiaResourceDialect,
17511 val_ref,
17512 decoder,
17513 inner_offset,
17514 inner_depth
17515 )?;
17516 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
17517 {
17518 return Err(fidl::Error::InvalidNumBytesInEnvelope);
17519 }
17520 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
17521 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
17522 }
17523 }
17524
17525 next_offset += envelope_size;
17526
17527 // Decode the remaining unknown envelopes.
17528 while next_offset < end_offset {
17529 _next_ordinal_to_read += 1;
17530 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17531 next_offset += envelope_size;
17532 }
17533
17534 Ok(())
17535 }
17536 }
17537
17538 impl AllocatorBindSharedCollectionRequest {
17539 #[inline(always)]
17540 fn max_ordinal_present(&self) -> u64 {
17541 if let Some(_) = self.buffer_collection_request {
17542 return 2;
17543 }
17544 if let Some(_) = self.token {
17545 return 1;
17546 }
17547 0
17548 }
17549 }
17550
17551 impl fidl::encoding::ResourceTypeMarker for AllocatorBindSharedCollectionRequest {
17552 type Borrowed<'a> = &'a mut Self;
17553 fn take_or_borrow<'a>(
17554 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
17555 ) -> Self::Borrowed<'a> {
17556 value
17557 }
17558 }
17559
17560 unsafe impl fidl::encoding::TypeMarker for AllocatorBindSharedCollectionRequest {
17561 type Owned = Self;
17562
17563 #[inline(always)]
17564 fn inline_align(_context: fidl::encoding::Context) -> usize {
17565 8
17566 }
17567
17568 #[inline(always)]
17569 fn inline_size(_context: fidl::encoding::Context) -> usize {
17570 16
17571 }
17572 }
17573
17574 unsafe impl
17575 fidl::encoding::Encode<
17576 AllocatorBindSharedCollectionRequest,
17577 fidl::encoding::DefaultFuchsiaResourceDialect,
17578 > for &mut AllocatorBindSharedCollectionRequest
17579 {
17580 unsafe fn encode(
17581 self,
17582 encoder: &mut fidl::encoding::Encoder<
17583 '_,
17584 fidl::encoding::DefaultFuchsiaResourceDialect,
17585 >,
17586 offset: usize,
17587 mut depth: fidl::encoding::Depth,
17588 ) -> fidl::Result<()> {
17589 encoder.debug_check_bounds::<AllocatorBindSharedCollectionRequest>(offset);
17590 // Vector header
17591 let max_ordinal: u64 = self.max_ordinal_present();
17592 encoder.write_num(max_ordinal, offset);
17593 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
17594 // Calling encoder.out_of_line_offset(0) is not allowed.
17595 if max_ordinal == 0 {
17596 return Ok(());
17597 }
17598 depth.increment()?;
17599 let envelope_size = 8;
17600 let bytes_len = max_ordinal as usize * envelope_size;
17601 #[allow(unused_variables)]
17602 let offset = encoder.out_of_line_offset(bytes_len);
17603 let mut _prev_end_offset: usize = 0;
17604 if 1 > max_ordinal {
17605 return Ok(());
17606 }
17607
17608 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17609 // are envelope_size bytes.
17610 let cur_offset: usize = (1 - 1) * envelope_size;
17611
17612 // Zero reserved fields.
17613 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17614
17615 // Safety:
17616 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17617 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17618 // envelope_size bytes, there is always sufficient room.
17619 fidl::encoding::encode_in_envelope_optional::<
17620 fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
17621 fidl::encoding::DefaultFuchsiaResourceDialect,
17622 >(
17623 self.token.as_mut().map(
17624 <fidl::encoding::Endpoint<
17625 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
17626 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
17627 ),
17628 encoder,
17629 offset + cur_offset,
17630 depth,
17631 )?;
17632
17633 _prev_end_offset = cur_offset + envelope_size;
17634 if 2 > max_ordinal {
17635 return Ok(());
17636 }
17637
17638 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17639 // are envelope_size bytes.
17640 let cur_offset: usize = (2 - 1) * envelope_size;
17641
17642 // Zero reserved fields.
17643 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17644
17645 // Safety:
17646 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17647 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17648 // envelope_size bytes, there is always sufficient room.
17649 fidl::encoding::encode_in_envelope_optional::<fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>, fidl::encoding::DefaultFuchsiaResourceDialect>(
17650 self.buffer_collection_request.as_mut().map(<fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow),
17651 encoder, offset + cur_offset, depth
17652 )?;
17653
17654 _prev_end_offset = cur_offset + envelope_size;
17655
17656 Ok(())
17657 }
17658 }
17659
17660 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
17661 for AllocatorBindSharedCollectionRequest
17662 {
17663 #[inline(always)]
17664 fn new_empty() -> Self {
17665 Self::default()
17666 }
17667
17668 unsafe fn decode(
17669 &mut self,
17670 decoder: &mut fidl::encoding::Decoder<
17671 '_,
17672 fidl::encoding::DefaultFuchsiaResourceDialect,
17673 >,
17674 offset: usize,
17675 mut depth: fidl::encoding::Depth,
17676 ) -> fidl::Result<()> {
17677 decoder.debug_check_bounds::<Self>(offset);
17678 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
17679 None => return Err(fidl::Error::NotNullable),
17680 Some(len) => len,
17681 };
17682 // Calling decoder.out_of_line_offset(0) is not allowed.
17683 if len == 0 {
17684 return Ok(());
17685 };
17686 depth.increment()?;
17687 let envelope_size = 8;
17688 let bytes_len = len * envelope_size;
17689 let offset = decoder.out_of_line_offset(bytes_len)?;
17690 // Decode the envelope for each type.
17691 let mut _next_ordinal_to_read = 0;
17692 let mut next_offset = offset;
17693 let end_offset = offset + bytes_len;
17694 _next_ordinal_to_read += 1;
17695 if next_offset >= end_offset {
17696 return Ok(());
17697 }
17698
17699 // Decode unknown envelopes for gaps in ordinals.
17700 while _next_ordinal_to_read < 1 {
17701 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17702 _next_ordinal_to_read += 1;
17703 next_offset += envelope_size;
17704 }
17705
17706 let next_out_of_line = decoder.next_out_of_line();
17707 let handles_before = decoder.remaining_handles();
17708 if let Some((inlined, num_bytes, num_handles)) =
17709 fidl::encoding::decode_envelope_header(decoder, next_offset)?
17710 {
17711 let member_inline_size = <fidl::encoding::Endpoint<
17712 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
17713 > as fidl::encoding::TypeMarker>::inline_size(
17714 decoder.context
17715 );
17716 if inlined != (member_inline_size <= 4) {
17717 return Err(fidl::Error::InvalidInlineBitInEnvelope);
17718 }
17719 let inner_offset;
17720 let mut inner_depth = depth.clone();
17721 if inlined {
17722 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
17723 inner_offset = next_offset;
17724 } else {
17725 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
17726 inner_depth.increment()?;
17727 }
17728 let val_ref = self.token.get_or_insert_with(|| {
17729 fidl::new_empty!(
17730 fidl::encoding::Endpoint<
17731 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
17732 >,
17733 fidl::encoding::DefaultFuchsiaResourceDialect
17734 )
17735 });
17736 fidl::decode!(
17737 fidl::encoding::Endpoint<
17738 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
17739 >,
17740 fidl::encoding::DefaultFuchsiaResourceDialect,
17741 val_ref,
17742 decoder,
17743 inner_offset,
17744 inner_depth
17745 )?;
17746 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
17747 {
17748 return Err(fidl::Error::InvalidNumBytesInEnvelope);
17749 }
17750 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
17751 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
17752 }
17753 }
17754
17755 next_offset += envelope_size;
17756 _next_ordinal_to_read += 1;
17757 if next_offset >= end_offset {
17758 return Ok(());
17759 }
17760
17761 // Decode unknown envelopes for gaps in ordinals.
17762 while _next_ordinal_to_read < 2 {
17763 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17764 _next_ordinal_to_read += 1;
17765 next_offset += envelope_size;
17766 }
17767
17768 let next_out_of_line = decoder.next_out_of_line();
17769 let handles_before = decoder.remaining_handles();
17770 if let Some((inlined, num_bytes, num_handles)) =
17771 fidl::encoding::decode_envelope_header(decoder, next_offset)?
17772 {
17773 let member_inline_size = <fidl::encoding::Endpoint<
17774 fidl::endpoints::ServerEnd<BufferCollectionMarker>,
17775 > as fidl::encoding::TypeMarker>::inline_size(
17776 decoder.context
17777 );
17778 if inlined != (member_inline_size <= 4) {
17779 return Err(fidl::Error::InvalidInlineBitInEnvelope);
17780 }
17781 let inner_offset;
17782 let mut inner_depth = depth.clone();
17783 if inlined {
17784 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
17785 inner_offset = next_offset;
17786 } else {
17787 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
17788 inner_depth.increment()?;
17789 }
17790 let val_ref = self.buffer_collection_request.get_or_insert_with(|| {
17791 fidl::new_empty!(
17792 fidl::encoding::Endpoint<
17793 fidl::endpoints::ServerEnd<BufferCollectionMarker>,
17794 >,
17795 fidl::encoding::DefaultFuchsiaResourceDialect
17796 )
17797 });
17798 fidl::decode!(
17799 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
17800 fidl::encoding::DefaultFuchsiaResourceDialect,
17801 val_ref,
17802 decoder,
17803 inner_offset,
17804 inner_depth
17805 )?;
17806 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
17807 {
17808 return Err(fidl::Error::InvalidNumBytesInEnvelope);
17809 }
17810 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
17811 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
17812 }
17813 }
17814
17815 next_offset += envelope_size;
17816
17817 // Decode the remaining unknown envelopes.
17818 while next_offset < end_offset {
17819 _next_ordinal_to_read += 1;
17820 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
17821 next_offset += envelope_size;
17822 }
17823
17824 Ok(())
17825 }
17826 }
17827
17828 impl AllocatorGetVmoInfoRequest {
17829 #[inline(always)]
17830 fn max_ordinal_present(&self) -> u64 {
17831 if let Some(_) = self.vmo_settings_to_check_ignore_size {
17832 return 6;
17833 }
17834 if let Some(_) = self.vmo_settings_to_check {
17835 return 5;
17836 }
17837 if let Some(_) = self.constraints_to_check {
17838 return 4;
17839 }
17840 if let Some(_) = self.need_single_buffer_settings {
17841 return 3;
17842 }
17843 if let Some(_) = self.need_weak {
17844 return 2;
17845 }
17846 if let Some(_) = self.vmo {
17847 return 1;
17848 }
17849 0
17850 }
17851 }
17852
17853 impl fidl::encoding::ResourceTypeMarker for AllocatorGetVmoInfoRequest {
17854 type Borrowed<'a> = &'a mut Self;
17855 fn take_or_borrow<'a>(
17856 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
17857 ) -> Self::Borrowed<'a> {
17858 value
17859 }
17860 }
17861
17862 unsafe impl fidl::encoding::TypeMarker for AllocatorGetVmoInfoRequest {
17863 type Owned = Self;
17864
17865 #[inline(always)]
17866 fn inline_align(_context: fidl::encoding::Context) -> usize {
17867 8
17868 }
17869
17870 #[inline(always)]
17871 fn inline_size(_context: fidl::encoding::Context) -> usize {
17872 16
17873 }
17874 }
17875
17876 unsafe impl
17877 fidl::encoding::Encode<
17878 AllocatorGetVmoInfoRequest,
17879 fidl::encoding::DefaultFuchsiaResourceDialect,
17880 > for &mut AllocatorGetVmoInfoRequest
17881 {
17882 unsafe fn encode(
17883 self,
17884 encoder: &mut fidl::encoding::Encoder<
17885 '_,
17886 fidl::encoding::DefaultFuchsiaResourceDialect,
17887 >,
17888 offset: usize,
17889 mut depth: fidl::encoding::Depth,
17890 ) -> fidl::Result<()> {
17891 encoder.debug_check_bounds::<AllocatorGetVmoInfoRequest>(offset);
17892 // Vector header
17893 let max_ordinal: u64 = self.max_ordinal_present();
17894 encoder.write_num(max_ordinal, offset);
17895 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
17896 // Calling encoder.out_of_line_offset(0) is not allowed.
17897 if max_ordinal == 0 {
17898 return Ok(());
17899 }
17900 depth.increment()?;
17901 let envelope_size = 8;
17902 let bytes_len = max_ordinal as usize * envelope_size;
17903 #[allow(unused_variables)]
17904 let offset = encoder.out_of_line_offset(bytes_len);
17905 let mut _prev_end_offset: usize = 0;
17906 if 1 > max_ordinal {
17907 return Ok(());
17908 }
17909
17910 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17911 // are envelope_size bytes.
17912 let cur_offset: usize = (1 - 1) * envelope_size;
17913
17914 // Zero reserved fields.
17915 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17916
17917 // Safety:
17918 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17919 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17920 // envelope_size bytes, there is always sufficient room.
17921 fidl::encoding::encode_in_envelope_optional::<
17922 fidl::encoding::HandleType<
17923 fidl::Vmo,
17924 { fidl::ObjectType::VMO.into_raw() },
17925 2147483648,
17926 >,
17927 fidl::encoding::DefaultFuchsiaResourceDialect,
17928 >(
17929 self.vmo.as_mut().map(
17930 <fidl::encoding::HandleType<
17931 fidl::Vmo,
17932 { fidl::ObjectType::VMO.into_raw() },
17933 2147483648,
17934 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
17935 ),
17936 encoder,
17937 offset + cur_offset,
17938 depth,
17939 )?;
17940
17941 _prev_end_offset = cur_offset + envelope_size;
17942 if 2 > 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 = (2 - 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 bool,
17959 fidl::encoding::DefaultFuchsiaResourceDialect,
17960 >(
17961 self.need_weak.as_ref().map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
17962 encoder,
17963 offset + cur_offset,
17964 depth,
17965 )?;
17966
17967 _prev_end_offset = cur_offset + envelope_size;
17968 if 3 > max_ordinal {
17969 return Ok(());
17970 }
17971
17972 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
17973 // are envelope_size bytes.
17974 let cur_offset: usize = (3 - 1) * envelope_size;
17975
17976 // Zero reserved fields.
17977 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
17978
17979 // Safety:
17980 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
17981 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
17982 // envelope_size bytes, there is always sufficient room.
17983 fidl::encoding::encode_in_envelope_optional::<
17984 bool,
17985 fidl::encoding::DefaultFuchsiaResourceDialect,
17986 >(
17987 self.need_single_buffer_settings
17988 .as_ref()
17989 .map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
17990 encoder,
17991 offset + cur_offset,
17992 depth,
17993 )?;
17994
17995 _prev_end_offset = cur_offset + envelope_size;
17996 if 4 > max_ordinal {
17997 return Ok(());
17998 }
17999
18000 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18001 // are envelope_size bytes.
18002 let cur_offset: usize = (4 - 1) * envelope_size;
18003
18004 // Zero reserved fields.
18005 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18006
18007 // Safety:
18008 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18009 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18010 // envelope_size bytes, there is always sufficient room.
18011 fidl::encoding::encode_in_envelope_optional::<
18012 BufferCollectionConstraints,
18013 fidl::encoding::DefaultFuchsiaResourceDialect,
18014 >(
18015 self.constraints_to_check
18016 .as_ref()
18017 .map(<BufferCollectionConstraints as fidl::encoding::ValueTypeMarker>::borrow),
18018 encoder,
18019 offset + cur_offset,
18020 depth,
18021 )?;
18022
18023 _prev_end_offset = cur_offset + envelope_size;
18024 if 5 > max_ordinal {
18025 return Ok(());
18026 }
18027
18028 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18029 // are envelope_size bytes.
18030 let cur_offset: usize = (5 - 1) * envelope_size;
18031
18032 // Zero reserved fields.
18033 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18034
18035 // Safety:
18036 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18037 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18038 // envelope_size bytes, there is always sufficient room.
18039 fidl::encoding::encode_in_envelope_optional::<
18040 fidl::encoding::HandleType<
18041 fidl::Vmo,
18042 { fidl::ObjectType::VMO.into_raw() },
18043 2147483648,
18044 >,
18045 fidl::encoding::DefaultFuchsiaResourceDialect,
18046 >(
18047 self.vmo_settings_to_check.as_mut().map(
18048 <fidl::encoding::HandleType<
18049 fidl::Vmo,
18050 { fidl::ObjectType::VMO.into_raw() },
18051 2147483648,
18052 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
18053 ),
18054 encoder,
18055 offset + cur_offset,
18056 depth,
18057 )?;
18058
18059 _prev_end_offset = cur_offset + envelope_size;
18060 if 6 > 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 = (6 - 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 bool,
18077 fidl::encoding::DefaultFuchsiaResourceDialect,
18078 >(
18079 self.vmo_settings_to_check_ignore_size
18080 .as_ref()
18081 .map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
18082 encoder,
18083 offset + cur_offset,
18084 depth,
18085 )?;
18086
18087 _prev_end_offset = cur_offset + envelope_size;
18088
18089 Ok(())
18090 }
18091 }
18092
18093 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
18094 for AllocatorGetVmoInfoRequest
18095 {
18096 #[inline(always)]
18097 fn new_empty() -> Self {
18098 Self::default()
18099 }
18100
18101 unsafe fn decode(
18102 &mut self,
18103 decoder: &mut fidl::encoding::Decoder<
18104 '_,
18105 fidl::encoding::DefaultFuchsiaResourceDialect,
18106 >,
18107 offset: usize,
18108 mut depth: fidl::encoding::Depth,
18109 ) -> fidl::Result<()> {
18110 decoder.debug_check_bounds::<Self>(offset);
18111 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
18112 None => return Err(fidl::Error::NotNullable),
18113 Some(len) => len,
18114 };
18115 // Calling decoder.out_of_line_offset(0) is not allowed.
18116 if len == 0 {
18117 return Ok(());
18118 };
18119 depth.increment()?;
18120 let envelope_size = 8;
18121 let bytes_len = len * envelope_size;
18122 let offset = decoder.out_of_line_offset(bytes_len)?;
18123 // Decode the envelope for each type.
18124 let mut _next_ordinal_to_read = 0;
18125 let mut next_offset = offset;
18126 let end_offset = offset + bytes_len;
18127 _next_ordinal_to_read += 1;
18128 if next_offset >= end_offset {
18129 return Ok(());
18130 }
18131
18132 // Decode unknown envelopes for gaps in ordinals.
18133 while _next_ordinal_to_read < 1 {
18134 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18135 _next_ordinal_to_read += 1;
18136 next_offset += envelope_size;
18137 }
18138
18139 let next_out_of_line = decoder.next_out_of_line();
18140 let handles_before = decoder.remaining_handles();
18141 if let Some((inlined, num_bytes, num_handles)) =
18142 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18143 {
18144 let member_inline_size = <fidl::encoding::HandleType<
18145 fidl::Vmo,
18146 { fidl::ObjectType::VMO.into_raw() },
18147 2147483648,
18148 > as fidl::encoding::TypeMarker>::inline_size(
18149 decoder.context
18150 );
18151 if inlined != (member_inline_size <= 4) {
18152 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18153 }
18154 let inner_offset;
18155 let mut inner_depth = depth.clone();
18156 if inlined {
18157 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18158 inner_offset = next_offset;
18159 } else {
18160 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18161 inner_depth.increment()?;
18162 }
18163 let val_ref =
18164 self.vmo.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
18165 fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
18166 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18167 {
18168 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18169 }
18170 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18171 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18172 }
18173 }
18174
18175 next_offset += envelope_size;
18176 _next_ordinal_to_read += 1;
18177 if next_offset >= end_offset {
18178 return Ok(());
18179 }
18180
18181 // Decode unknown envelopes for gaps in ordinals.
18182 while _next_ordinal_to_read < 2 {
18183 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18184 _next_ordinal_to_read += 1;
18185 next_offset += envelope_size;
18186 }
18187
18188 let next_out_of_line = decoder.next_out_of_line();
18189 let handles_before = decoder.remaining_handles();
18190 if let Some((inlined, num_bytes, num_handles)) =
18191 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18192 {
18193 let member_inline_size =
18194 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
18195 if inlined != (member_inline_size <= 4) {
18196 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18197 }
18198 let inner_offset;
18199 let mut inner_depth = depth.clone();
18200 if inlined {
18201 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18202 inner_offset = next_offset;
18203 } else {
18204 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18205 inner_depth.increment()?;
18206 }
18207 let val_ref = self.need_weak.get_or_insert_with(|| {
18208 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
18209 });
18210 fidl::decode!(
18211 bool,
18212 fidl::encoding::DefaultFuchsiaResourceDialect,
18213 val_ref,
18214 decoder,
18215 inner_offset,
18216 inner_depth
18217 )?;
18218 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18219 {
18220 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18221 }
18222 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18223 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18224 }
18225 }
18226
18227 next_offset += envelope_size;
18228 _next_ordinal_to_read += 1;
18229 if next_offset >= end_offset {
18230 return Ok(());
18231 }
18232
18233 // Decode unknown envelopes for gaps in ordinals.
18234 while _next_ordinal_to_read < 3 {
18235 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18236 _next_ordinal_to_read += 1;
18237 next_offset += envelope_size;
18238 }
18239
18240 let next_out_of_line = decoder.next_out_of_line();
18241 let handles_before = decoder.remaining_handles();
18242 if let Some((inlined, num_bytes, num_handles)) =
18243 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18244 {
18245 let member_inline_size =
18246 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
18247 if inlined != (member_inline_size <= 4) {
18248 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18249 }
18250 let inner_offset;
18251 let mut inner_depth = depth.clone();
18252 if inlined {
18253 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18254 inner_offset = next_offset;
18255 } else {
18256 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18257 inner_depth.increment()?;
18258 }
18259 let val_ref = self.need_single_buffer_settings.get_or_insert_with(|| {
18260 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
18261 });
18262 fidl::decode!(
18263 bool,
18264 fidl::encoding::DefaultFuchsiaResourceDialect,
18265 val_ref,
18266 decoder,
18267 inner_offset,
18268 inner_depth
18269 )?;
18270 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18271 {
18272 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18273 }
18274 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18275 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18276 }
18277 }
18278
18279 next_offset += envelope_size;
18280 _next_ordinal_to_read += 1;
18281 if next_offset >= end_offset {
18282 return Ok(());
18283 }
18284
18285 // Decode unknown envelopes for gaps in ordinals.
18286 while _next_ordinal_to_read < 4 {
18287 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18288 _next_ordinal_to_read += 1;
18289 next_offset += envelope_size;
18290 }
18291
18292 let next_out_of_line = decoder.next_out_of_line();
18293 let handles_before = decoder.remaining_handles();
18294 if let Some((inlined, num_bytes, num_handles)) =
18295 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18296 {
18297 let member_inline_size =
18298 <BufferCollectionConstraints as fidl::encoding::TypeMarker>::inline_size(
18299 decoder.context,
18300 );
18301 if inlined != (member_inline_size <= 4) {
18302 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18303 }
18304 let inner_offset;
18305 let mut inner_depth = depth.clone();
18306 if inlined {
18307 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18308 inner_offset = next_offset;
18309 } else {
18310 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18311 inner_depth.increment()?;
18312 }
18313 let val_ref = self.constraints_to_check.get_or_insert_with(|| {
18314 fidl::new_empty!(
18315 BufferCollectionConstraints,
18316 fidl::encoding::DefaultFuchsiaResourceDialect
18317 )
18318 });
18319 fidl::decode!(
18320 BufferCollectionConstraints,
18321 fidl::encoding::DefaultFuchsiaResourceDialect,
18322 val_ref,
18323 decoder,
18324 inner_offset,
18325 inner_depth
18326 )?;
18327 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18328 {
18329 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18330 }
18331 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18332 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18333 }
18334 }
18335
18336 next_offset += envelope_size;
18337 _next_ordinal_to_read += 1;
18338 if next_offset >= end_offset {
18339 return Ok(());
18340 }
18341
18342 // Decode unknown envelopes for gaps in ordinals.
18343 while _next_ordinal_to_read < 5 {
18344 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18345 _next_ordinal_to_read += 1;
18346 next_offset += envelope_size;
18347 }
18348
18349 let next_out_of_line = decoder.next_out_of_line();
18350 let handles_before = decoder.remaining_handles();
18351 if let Some((inlined, num_bytes, num_handles)) =
18352 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18353 {
18354 let member_inline_size = <fidl::encoding::HandleType<
18355 fidl::Vmo,
18356 { fidl::ObjectType::VMO.into_raw() },
18357 2147483648,
18358 > as fidl::encoding::TypeMarker>::inline_size(
18359 decoder.context
18360 );
18361 if inlined != (member_inline_size <= 4) {
18362 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18363 }
18364 let inner_offset;
18365 let mut inner_depth = depth.clone();
18366 if inlined {
18367 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18368 inner_offset = next_offset;
18369 } else {
18370 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18371 inner_depth.increment()?;
18372 }
18373 let val_ref =
18374 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));
18375 fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
18376 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18377 {
18378 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18379 }
18380 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18381 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18382 }
18383 }
18384
18385 next_offset += envelope_size;
18386 _next_ordinal_to_read += 1;
18387 if next_offset >= end_offset {
18388 return Ok(());
18389 }
18390
18391 // Decode unknown envelopes for gaps in ordinals.
18392 while _next_ordinal_to_read < 6 {
18393 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18394 _next_ordinal_to_read += 1;
18395 next_offset += envelope_size;
18396 }
18397
18398 let next_out_of_line = decoder.next_out_of_line();
18399 let handles_before = decoder.remaining_handles();
18400 if let Some((inlined, num_bytes, num_handles)) =
18401 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18402 {
18403 let member_inline_size =
18404 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
18405 if inlined != (member_inline_size <= 4) {
18406 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18407 }
18408 let inner_offset;
18409 let mut inner_depth = depth.clone();
18410 if inlined {
18411 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18412 inner_offset = next_offset;
18413 } else {
18414 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18415 inner_depth.increment()?;
18416 }
18417 let val_ref = self.vmo_settings_to_check_ignore_size.get_or_insert_with(|| {
18418 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
18419 });
18420 fidl::decode!(
18421 bool,
18422 fidl::encoding::DefaultFuchsiaResourceDialect,
18423 val_ref,
18424 decoder,
18425 inner_offset,
18426 inner_depth
18427 )?;
18428 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18429 {
18430 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18431 }
18432 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18433 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18434 }
18435 }
18436
18437 next_offset += envelope_size;
18438
18439 // Decode the remaining unknown envelopes.
18440 while next_offset < end_offset {
18441 _next_ordinal_to_read += 1;
18442 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18443 next_offset += envelope_size;
18444 }
18445
18446 Ok(())
18447 }
18448 }
18449
18450 impl AllocatorGetVmoInfoResponse {
18451 #[inline(always)]
18452 fn max_ordinal_present(&self) -> u64 {
18453 if let Some(_) = self.vmo_settings_match {
18454 return 7;
18455 }
18456 if let Some(_) = self.constraints_ok {
18457 return 6;
18458 }
18459 if let Some(_) = self.single_buffer_settings {
18460 return 5;
18461 }
18462 if let Some(_) = self.weak_vmo {
18463 return 4;
18464 }
18465 if let Some(_) = self.close_weak_asap {
18466 return 3;
18467 }
18468 if let Some(_) = self.buffer_index {
18469 return 2;
18470 }
18471 if let Some(_) = self.buffer_collection_id {
18472 return 1;
18473 }
18474 0
18475 }
18476 }
18477
18478 impl fidl::encoding::ResourceTypeMarker for AllocatorGetVmoInfoResponse {
18479 type Borrowed<'a> = &'a mut Self;
18480 fn take_or_borrow<'a>(
18481 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
18482 ) -> Self::Borrowed<'a> {
18483 value
18484 }
18485 }
18486
18487 unsafe impl fidl::encoding::TypeMarker for AllocatorGetVmoInfoResponse {
18488 type Owned = Self;
18489
18490 #[inline(always)]
18491 fn inline_align(_context: fidl::encoding::Context) -> usize {
18492 8
18493 }
18494
18495 #[inline(always)]
18496 fn inline_size(_context: fidl::encoding::Context) -> usize {
18497 16
18498 }
18499 }
18500
18501 unsafe impl
18502 fidl::encoding::Encode<
18503 AllocatorGetVmoInfoResponse,
18504 fidl::encoding::DefaultFuchsiaResourceDialect,
18505 > for &mut AllocatorGetVmoInfoResponse
18506 {
18507 unsafe fn encode(
18508 self,
18509 encoder: &mut fidl::encoding::Encoder<
18510 '_,
18511 fidl::encoding::DefaultFuchsiaResourceDialect,
18512 >,
18513 offset: usize,
18514 mut depth: fidl::encoding::Depth,
18515 ) -> fidl::Result<()> {
18516 encoder.debug_check_bounds::<AllocatorGetVmoInfoResponse>(offset);
18517 // Vector header
18518 let max_ordinal: u64 = self.max_ordinal_present();
18519 encoder.write_num(max_ordinal, offset);
18520 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
18521 // Calling encoder.out_of_line_offset(0) is not allowed.
18522 if max_ordinal == 0 {
18523 return Ok(());
18524 }
18525 depth.increment()?;
18526 let envelope_size = 8;
18527 let bytes_len = max_ordinal as usize * envelope_size;
18528 #[allow(unused_variables)]
18529 let offset = encoder.out_of_line_offset(bytes_len);
18530 let mut _prev_end_offset: usize = 0;
18531 if 1 > max_ordinal {
18532 return Ok(());
18533 }
18534
18535 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18536 // are envelope_size bytes.
18537 let cur_offset: usize = (1 - 1) * envelope_size;
18538
18539 // Zero reserved fields.
18540 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18541
18542 // Safety:
18543 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18544 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18545 // envelope_size bytes, there is always sufficient room.
18546 fidl::encoding::encode_in_envelope_optional::<
18547 u64,
18548 fidl::encoding::DefaultFuchsiaResourceDialect,
18549 >(
18550 self.buffer_collection_id
18551 .as_ref()
18552 .map(<u64 as fidl::encoding::ValueTypeMarker>::borrow),
18553 encoder,
18554 offset + cur_offset,
18555 depth,
18556 )?;
18557
18558 _prev_end_offset = cur_offset + envelope_size;
18559 if 2 > max_ordinal {
18560 return Ok(());
18561 }
18562
18563 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18564 // are envelope_size bytes.
18565 let cur_offset: usize = (2 - 1) * envelope_size;
18566
18567 // Zero reserved fields.
18568 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18569
18570 // Safety:
18571 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18572 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18573 // envelope_size bytes, there is always sufficient room.
18574 fidl::encoding::encode_in_envelope_optional::<
18575 u64,
18576 fidl::encoding::DefaultFuchsiaResourceDialect,
18577 >(
18578 self.buffer_index.as_ref().map(<u64 as fidl::encoding::ValueTypeMarker>::borrow),
18579 encoder,
18580 offset + cur_offset,
18581 depth,
18582 )?;
18583
18584 _prev_end_offset = cur_offset + envelope_size;
18585 if 3 > max_ordinal {
18586 return Ok(());
18587 }
18588
18589 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18590 // are envelope_size bytes.
18591 let cur_offset: usize = (3 - 1) * envelope_size;
18592
18593 // Zero reserved fields.
18594 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18595
18596 // Safety:
18597 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18598 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18599 // envelope_size bytes, there is always sufficient room.
18600 fidl::encoding::encode_in_envelope_optional::<
18601 fidl::encoding::HandleType<
18602 fidl::EventPair,
18603 { fidl::ObjectType::EVENTPAIR.into_raw() },
18604 2147483648,
18605 >,
18606 fidl::encoding::DefaultFuchsiaResourceDialect,
18607 >(
18608 self.close_weak_asap.as_mut().map(
18609 <fidl::encoding::HandleType<
18610 fidl::EventPair,
18611 { fidl::ObjectType::EVENTPAIR.into_raw() },
18612 2147483648,
18613 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
18614 ),
18615 encoder,
18616 offset + cur_offset,
18617 depth,
18618 )?;
18619
18620 _prev_end_offset = cur_offset + envelope_size;
18621 if 4 > 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 = (4 - 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::Vmo,
18639 { fidl::ObjectType::VMO.into_raw() },
18640 2147483648,
18641 >,
18642 fidl::encoding::DefaultFuchsiaResourceDialect,
18643 >(
18644 self.weak_vmo.as_mut().map(
18645 <fidl::encoding::HandleType<
18646 fidl::Vmo,
18647 { fidl::ObjectType::VMO.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 5 > 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 = (5 - 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 SingleBufferSettings,
18674 fidl::encoding::DefaultFuchsiaResourceDialect,
18675 >(
18676 self.single_buffer_settings
18677 .as_ref()
18678 .map(<SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow),
18679 encoder,
18680 offset + cur_offset,
18681 depth,
18682 )?;
18683
18684 _prev_end_offset = cur_offset + envelope_size;
18685 if 6 > max_ordinal {
18686 return Ok(());
18687 }
18688
18689 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18690 // are envelope_size bytes.
18691 let cur_offset: usize = (6 - 1) * envelope_size;
18692
18693 // Zero reserved fields.
18694 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18695
18696 // Safety:
18697 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18698 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18699 // envelope_size bytes, there is always sufficient room.
18700 fidl::encoding::encode_in_envelope_optional::<
18701 bool,
18702 fidl::encoding::DefaultFuchsiaResourceDialect,
18703 >(
18704 self.constraints_ok.as_ref().map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
18705 encoder,
18706 offset + cur_offset,
18707 depth,
18708 )?;
18709
18710 _prev_end_offset = cur_offset + envelope_size;
18711 if 7 > max_ordinal {
18712 return Ok(());
18713 }
18714
18715 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
18716 // are envelope_size bytes.
18717 let cur_offset: usize = (7 - 1) * envelope_size;
18718
18719 // Zero reserved fields.
18720 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
18721
18722 // Safety:
18723 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
18724 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
18725 // envelope_size bytes, there is always sufficient room.
18726 fidl::encoding::encode_in_envelope_optional::<
18727 bool,
18728 fidl::encoding::DefaultFuchsiaResourceDialect,
18729 >(
18730 self.vmo_settings_match
18731 .as_ref()
18732 .map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
18733 encoder,
18734 offset + cur_offset,
18735 depth,
18736 )?;
18737
18738 _prev_end_offset = cur_offset + envelope_size;
18739
18740 Ok(())
18741 }
18742 }
18743
18744 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
18745 for AllocatorGetVmoInfoResponse
18746 {
18747 #[inline(always)]
18748 fn new_empty() -> Self {
18749 Self::default()
18750 }
18751
18752 unsafe fn decode(
18753 &mut self,
18754 decoder: &mut fidl::encoding::Decoder<
18755 '_,
18756 fidl::encoding::DefaultFuchsiaResourceDialect,
18757 >,
18758 offset: usize,
18759 mut depth: fidl::encoding::Depth,
18760 ) -> fidl::Result<()> {
18761 decoder.debug_check_bounds::<Self>(offset);
18762 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
18763 None => return Err(fidl::Error::NotNullable),
18764 Some(len) => len,
18765 };
18766 // Calling decoder.out_of_line_offset(0) is not allowed.
18767 if len == 0 {
18768 return Ok(());
18769 };
18770 depth.increment()?;
18771 let envelope_size = 8;
18772 let bytes_len = len * envelope_size;
18773 let offset = decoder.out_of_line_offset(bytes_len)?;
18774 // Decode the envelope for each type.
18775 let mut _next_ordinal_to_read = 0;
18776 let mut next_offset = offset;
18777 let end_offset = offset + bytes_len;
18778 _next_ordinal_to_read += 1;
18779 if next_offset >= end_offset {
18780 return Ok(());
18781 }
18782
18783 // Decode unknown envelopes for gaps in ordinals.
18784 while _next_ordinal_to_read < 1 {
18785 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18786 _next_ordinal_to_read += 1;
18787 next_offset += envelope_size;
18788 }
18789
18790 let next_out_of_line = decoder.next_out_of_line();
18791 let handles_before = decoder.remaining_handles();
18792 if let Some((inlined, num_bytes, num_handles)) =
18793 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18794 {
18795 let member_inline_size =
18796 <u64 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
18797 if inlined != (member_inline_size <= 4) {
18798 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18799 }
18800 let inner_offset;
18801 let mut inner_depth = depth.clone();
18802 if inlined {
18803 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18804 inner_offset = next_offset;
18805 } else {
18806 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18807 inner_depth.increment()?;
18808 }
18809 let val_ref = self.buffer_collection_id.get_or_insert_with(|| {
18810 fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect)
18811 });
18812 fidl::decode!(
18813 u64,
18814 fidl::encoding::DefaultFuchsiaResourceDialect,
18815 val_ref,
18816 decoder,
18817 inner_offset,
18818 inner_depth
18819 )?;
18820 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18821 {
18822 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18823 }
18824 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18825 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18826 }
18827 }
18828
18829 next_offset += envelope_size;
18830 _next_ordinal_to_read += 1;
18831 if next_offset >= end_offset {
18832 return Ok(());
18833 }
18834
18835 // Decode unknown envelopes for gaps in ordinals.
18836 while _next_ordinal_to_read < 2 {
18837 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18838 _next_ordinal_to_read += 1;
18839 next_offset += envelope_size;
18840 }
18841
18842 let next_out_of_line = decoder.next_out_of_line();
18843 let handles_before = decoder.remaining_handles();
18844 if let Some((inlined, num_bytes, num_handles)) =
18845 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18846 {
18847 let member_inline_size =
18848 <u64 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
18849 if inlined != (member_inline_size <= 4) {
18850 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18851 }
18852 let inner_offset;
18853 let mut inner_depth = depth.clone();
18854 if inlined {
18855 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18856 inner_offset = next_offset;
18857 } else {
18858 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18859 inner_depth.increment()?;
18860 }
18861 let val_ref = self.buffer_index.get_or_insert_with(|| {
18862 fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect)
18863 });
18864 fidl::decode!(
18865 u64,
18866 fidl::encoding::DefaultFuchsiaResourceDialect,
18867 val_ref,
18868 decoder,
18869 inner_offset,
18870 inner_depth
18871 )?;
18872 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18873 {
18874 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18875 }
18876 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18877 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18878 }
18879 }
18880
18881 next_offset += envelope_size;
18882 _next_ordinal_to_read += 1;
18883 if next_offset >= end_offset {
18884 return Ok(());
18885 }
18886
18887 // Decode unknown envelopes for gaps in ordinals.
18888 while _next_ordinal_to_read < 3 {
18889 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18890 _next_ordinal_to_read += 1;
18891 next_offset += envelope_size;
18892 }
18893
18894 let next_out_of_line = decoder.next_out_of_line();
18895 let handles_before = decoder.remaining_handles();
18896 if let Some((inlined, num_bytes, num_handles)) =
18897 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18898 {
18899 let member_inline_size = <fidl::encoding::HandleType<
18900 fidl::EventPair,
18901 { fidl::ObjectType::EVENTPAIR.into_raw() },
18902 2147483648,
18903 > as fidl::encoding::TypeMarker>::inline_size(
18904 decoder.context
18905 );
18906 if inlined != (member_inline_size <= 4) {
18907 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18908 }
18909 let inner_offset;
18910 let mut inner_depth = depth.clone();
18911 if inlined {
18912 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18913 inner_offset = next_offset;
18914 } else {
18915 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18916 inner_depth.increment()?;
18917 }
18918 let val_ref =
18919 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));
18920 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
18921 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18922 {
18923 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18924 }
18925 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18926 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18927 }
18928 }
18929
18930 next_offset += envelope_size;
18931 _next_ordinal_to_read += 1;
18932 if next_offset >= end_offset {
18933 return Ok(());
18934 }
18935
18936 // Decode unknown envelopes for gaps in ordinals.
18937 while _next_ordinal_to_read < 4 {
18938 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18939 _next_ordinal_to_read += 1;
18940 next_offset += envelope_size;
18941 }
18942
18943 let next_out_of_line = decoder.next_out_of_line();
18944 let handles_before = decoder.remaining_handles();
18945 if let Some((inlined, num_bytes, num_handles)) =
18946 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18947 {
18948 let member_inline_size = <fidl::encoding::HandleType<
18949 fidl::Vmo,
18950 { fidl::ObjectType::VMO.into_raw() },
18951 2147483648,
18952 > as fidl::encoding::TypeMarker>::inline_size(
18953 decoder.context
18954 );
18955 if inlined != (member_inline_size <= 4) {
18956 return Err(fidl::Error::InvalidInlineBitInEnvelope);
18957 }
18958 let inner_offset;
18959 let mut inner_depth = depth.clone();
18960 if inlined {
18961 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
18962 inner_offset = next_offset;
18963 } else {
18964 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
18965 inner_depth.increment()?;
18966 }
18967 let val_ref =
18968 self.weak_vmo.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
18969 fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
18970 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
18971 {
18972 return Err(fidl::Error::InvalidNumBytesInEnvelope);
18973 }
18974 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
18975 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
18976 }
18977 }
18978
18979 next_offset += envelope_size;
18980 _next_ordinal_to_read += 1;
18981 if next_offset >= end_offset {
18982 return Ok(());
18983 }
18984
18985 // Decode unknown envelopes for gaps in ordinals.
18986 while _next_ordinal_to_read < 5 {
18987 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
18988 _next_ordinal_to_read += 1;
18989 next_offset += envelope_size;
18990 }
18991
18992 let next_out_of_line = decoder.next_out_of_line();
18993 let handles_before = decoder.remaining_handles();
18994 if let Some((inlined, num_bytes, num_handles)) =
18995 fidl::encoding::decode_envelope_header(decoder, next_offset)?
18996 {
18997 let member_inline_size =
18998 <SingleBufferSettings as fidl::encoding::TypeMarker>::inline_size(
18999 decoder.context,
19000 );
19001 if inlined != (member_inline_size <= 4) {
19002 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19003 }
19004 let inner_offset;
19005 let mut inner_depth = depth.clone();
19006 if inlined {
19007 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19008 inner_offset = next_offset;
19009 } else {
19010 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19011 inner_depth.increment()?;
19012 }
19013 let val_ref = self.single_buffer_settings.get_or_insert_with(|| {
19014 fidl::new_empty!(
19015 SingleBufferSettings,
19016 fidl::encoding::DefaultFuchsiaResourceDialect
19017 )
19018 });
19019 fidl::decode!(
19020 SingleBufferSettings,
19021 fidl::encoding::DefaultFuchsiaResourceDialect,
19022 val_ref,
19023 decoder,
19024 inner_offset,
19025 inner_depth
19026 )?;
19027 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19028 {
19029 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19030 }
19031 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19032 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19033 }
19034 }
19035
19036 next_offset += envelope_size;
19037 _next_ordinal_to_read += 1;
19038 if next_offset >= end_offset {
19039 return Ok(());
19040 }
19041
19042 // Decode unknown envelopes for gaps in ordinals.
19043 while _next_ordinal_to_read < 6 {
19044 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19045 _next_ordinal_to_read += 1;
19046 next_offset += envelope_size;
19047 }
19048
19049 let next_out_of_line = decoder.next_out_of_line();
19050 let handles_before = decoder.remaining_handles();
19051 if let Some((inlined, num_bytes, num_handles)) =
19052 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19053 {
19054 let member_inline_size =
19055 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
19056 if inlined != (member_inline_size <= 4) {
19057 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19058 }
19059 let inner_offset;
19060 let mut inner_depth = depth.clone();
19061 if inlined {
19062 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19063 inner_offset = next_offset;
19064 } else {
19065 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19066 inner_depth.increment()?;
19067 }
19068 let val_ref = self.constraints_ok.get_or_insert_with(|| {
19069 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
19070 });
19071 fidl::decode!(
19072 bool,
19073 fidl::encoding::DefaultFuchsiaResourceDialect,
19074 val_ref,
19075 decoder,
19076 inner_offset,
19077 inner_depth
19078 )?;
19079 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19080 {
19081 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19082 }
19083 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19084 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19085 }
19086 }
19087
19088 next_offset += envelope_size;
19089 _next_ordinal_to_read += 1;
19090 if next_offset >= end_offset {
19091 return Ok(());
19092 }
19093
19094 // Decode unknown envelopes for gaps in ordinals.
19095 while _next_ordinal_to_read < 7 {
19096 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19097 _next_ordinal_to_read += 1;
19098 next_offset += envelope_size;
19099 }
19100
19101 let next_out_of_line = decoder.next_out_of_line();
19102 let handles_before = decoder.remaining_handles();
19103 if let Some((inlined, num_bytes, num_handles)) =
19104 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19105 {
19106 let member_inline_size =
19107 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
19108 if inlined != (member_inline_size <= 4) {
19109 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19110 }
19111 let inner_offset;
19112 let mut inner_depth = depth.clone();
19113 if inlined {
19114 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19115 inner_offset = next_offset;
19116 } else {
19117 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19118 inner_depth.increment()?;
19119 }
19120 let val_ref = self.vmo_settings_match.get_or_insert_with(|| {
19121 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
19122 });
19123 fidl::decode!(
19124 bool,
19125 fidl::encoding::DefaultFuchsiaResourceDialect,
19126 val_ref,
19127 decoder,
19128 inner_offset,
19129 inner_depth
19130 )?;
19131 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19132 {
19133 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19134 }
19135 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19136 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19137 }
19138 }
19139
19140 next_offset += envelope_size;
19141
19142 // Decode the remaining unknown envelopes.
19143 while next_offset < end_offset {
19144 _next_ordinal_to_read += 1;
19145 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19146 next_offset += envelope_size;
19147 }
19148
19149 Ok(())
19150 }
19151 }
19152
19153 impl BufferCollectionAttachLifetimeTrackingRequest {
19154 #[inline(always)]
19155 fn max_ordinal_present(&self) -> u64 {
19156 if let Some(_) = self.buffers_remaining {
19157 return 2;
19158 }
19159 if let Some(_) = self.server_end {
19160 return 1;
19161 }
19162 0
19163 }
19164 }
19165
19166 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
19167 type Borrowed<'a> = &'a mut Self;
19168 fn take_or_borrow<'a>(
19169 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
19170 ) -> Self::Borrowed<'a> {
19171 value
19172 }
19173 }
19174
19175 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
19176 type Owned = Self;
19177
19178 #[inline(always)]
19179 fn inline_align(_context: fidl::encoding::Context) -> usize {
19180 8
19181 }
19182
19183 #[inline(always)]
19184 fn inline_size(_context: fidl::encoding::Context) -> usize {
19185 16
19186 }
19187 }
19188
19189 unsafe impl
19190 fidl::encoding::Encode<
19191 BufferCollectionAttachLifetimeTrackingRequest,
19192 fidl::encoding::DefaultFuchsiaResourceDialect,
19193 > for &mut BufferCollectionAttachLifetimeTrackingRequest
19194 {
19195 unsafe fn encode(
19196 self,
19197 encoder: &mut fidl::encoding::Encoder<
19198 '_,
19199 fidl::encoding::DefaultFuchsiaResourceDialect,
19200 >,
19201 offset: usize,
19202 mut depth: fidl::encoding::Depth,
19203 ) -> fidl::Result<()> {
19204 encoder.debug_check_bounds::<BufferCollectionAttachLifetimeTrackingRequest>(offset);
19205 // Vector header
19206 let max_ordinal: u64 = self.max_ordinal_present();
19207 encoder.write_num(max_ordinal, offset);
19208 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
19209 // Calling encoder.out_of_line_offset(0) is not allowed.
19210 if max_ordinal == 0 {
19211 return Ok(());
19212 }
19213 depth.increment()?;
19214 let envelope_size = 8;
19215 let bytes_len = max_ordinal as usize * envelope_size;
19216 #[allow(unused_variables)]
19217 let offset = encoder.out_of_line_offset(bytes_len);
19218 let mut _prev_end_offset: usize = 0;
19219 if 1 > max_ordinal {
19220 return Ok(());
19221 }
19222
19223 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19224 // are envelope_size bytes.
19225 let cur_offset: usize = (1 - 1) * envelope_size;
19226
19227 // Zero reserved fields.
19228 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19229
19230 // Safety:
19231 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19232 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19233 // envelope_size bytes, there is always sufficient room.
19234 fidl::encoding::encode_in_envelope_optional::<
19235 fidl::encoding::HandleType<
19236 fidl::EventPair,
19237 { fidl::ObjectType::EVENTPAIR.into_raw() },
19238 2147483648,
19239 >,
19240 fidl::encoding::DefaultFuchsiaResourceDialect,
19241 >(
19242 self.server_end.as_mut().map(
19243 <fidl::encoding::HandleType<
19244 fidl::EventPair,
19245 { fidl::ObjectType::EVENTPAIR.into_raw() },
19246 2147483648,
19247 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
19248 ),
19249 encoder,
19250 offset + cur_offset,
19251 depth,
19252 )?;
19253
19254 _prev_end_offset = cur_offset + envelope_size;
19255 if 2 > 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 = (2 - 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 u32,
19272 fidl::encoding::DefaultFuchsiaResourceDialect,
19273 >(
19274 self.buffers_remaining
19275 .as_ref()
19276 .map(<u32 as fidl::encoding::ValueTypeMarker>::borrow),
19277 encoder,
19278 offset + cur_offset,
19279 depth,
19280 )?;
19281
19282 _prev_end_offset = cur_offset + envelope_size;
19283
19284 Ok(())
19285 }
19286 }
19287
19288 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
19289 for BufferCollectionAttachLifetimeTrackingRequest
19290 {
19291 #[inline(always)]
19292 fn new_empty() -> Self {
19293 Self::default()
19294 }
19295
19296 unsafe fn decode(
19297 &mut self,
19298 decoder: &mut fidl::encoding::Decoder<
19299 '_,
19300 fidl::encoding::DefaultFuchsiaResourceDialect,
19301 >,
19302 offset: usize,
19303 mut depth: fidl::encoding::Depth,
19304 ) -> fidl::Result<()> {
19305 decoder.debug_check_bounds::<Self>(offset);
19306 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
19307 None => return Err(fidl::Error::NotNullable),
19308 Some(len) => len,
19309 };
19310 // Calling decoder.out_of_line_offset(0) is not allowed.
19311 if len == 0 {
19312 return Ok(());
19313 };
19314 depth.increment()?;
19315 let envelope_size = 8;
19316 let bytes_len = len * envelope_size;
19317 let offset = decoder.out_of_line_offset(bytes_len)?;
19318 // Decode the envelope for each type.
19319 let mut _next_ordinal_to_read = 0;
19320 let mut next_offset = offset;
19321 let end_offset = offset + bytes_len;
19322 _next_ordinal_to_read += 1;
19323 if next_offset >= end_offset {
19324 return Ok(());
19325 }
19326
19327 // Decode unknown envelopes for gaps in ordinals.
19328 while _next_ordinal_to_read < 1 {
19329 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19330 _next_ordinal_to_read += 1;
19331 next_offset += envelope_size;
19332 }
19333
19334 let next_out_of_line = decoder.next_out_of_line();
19335 let handles_before = decoder.remaining_handles();
19336 if let Some((inlined, num_bytes, num_handles)) =
19337 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19338 {
19339 let member_inline_size = <fidl::encoding::HandleType<
19340 fidl::EventPair,
19341 { fidl::ObjectType::EVENTPAIR.into_raw() },
19342 2147483648,
19343 > as fidl::encoding::TypeMarker>::inline_size(
19344 decoder.context
19345 );
19346 if inlined != (member_inline_size <= 4) {
19347 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19348 }
19349 let inner_offset;
19350 let mut inner_depth = depth.clone();
19351 if inlined {
19352 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19353 inner_offset = next_offset;
19354 } else {
19355 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19356 inner_depth.increment()?;
19357 }
19358 let val_ref =
19359 self.server_end.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
19360 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
19361 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19362 {
19363 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19364 }
19365 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19366 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19367 }
19368 }
19369
19370 next_offset += envelope_size;
19371 _next_ordinal_to_read += 1;
19372 if next_offset >= end_offset {
19373 return Ok(());
19374 }
19375
19376 // Decode unknown envelopes for gaps in ordinals.
19377 while _next_ordinal_to_read < 2 {
19378 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19379 _next_ordinal_to_read += 1;
19380 next_offset += envelope_size;
19381 }
19382
19383 let next_out_of_line = decoder.next_out_of_line();
19384 let handles_before = decoder.remaining_handles();
19385 if let Some((inlined, num_bytes, num_handles)) =
19386 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19387 {
19388 let member_inline_size =
19389 <u32 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
19390 if inlined != (member_inline_size <= 4) {
19391 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19392 }
19393 let inner_offset;
19394 let mut inner_depth = depth.clone();
19395 if inlined {
19396 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19397 inner_offset = next_offset;
19398 } else {
19399 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19400 inner_depth.increment()?;
19401 }
19402 let val_ref = self.buffers_remaining.get_or_insert_with(|| {
19403 fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect)
19404 });
19405 fidl::decode!(
19406 u32,
19407 fidl::encoding::DefaultFuchsiaResourceDialect,
19408 val_ref,
19409 decoder,
19410 inner_offset,
19411 inner_depth
19412 )?;
19413 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19414 {
19415 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19416 }
19417 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19418 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19419 }
19420 }
19421
19422 next_offset += envelope_size;
19423
19424 // Decode the remaining unknown envelopes.
19425 while next_offset < end_offset {
19426 _next_ordinal_to_read += 1;
19427 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19428 next_offset += envelope_size;
19429 }
19430
19431 Ok(())
19432 }
19433 }
19434
19435 impl BufferCollectionAttachTokenRequest {
19436 #[inline(always)]
19437 fn max_ordinal_present(&self) -> u64 {
19438 if let Some(_) = self.token_request {
19439 return 2;
19440 }
19441 if let Some(_) = self.rights_attenuation_mask {
19442 return 1;
19443 }
19444 0
19445 }
19446 }
19447
19448 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachTokenRequest {
19449 type Borrowed<'a> = &'a mut Self;
19450 fn take_or_borrow<'a>(
19451 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
19452 ) -> Self::Borrowed<'a> {
19453 value
19454 }
19455 }
19456
19457 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachTokenRequest {
19458 type Owned = Self;
19459
19460 #[inline(always)]
19461 fn inline_align(_context: fidl::encoding::Context) -> usize {
19462 8
19463 }
19464
19465 #[inline(always)]
19466 fn inline_size(_context: fidl::encoding::Context) -> usize {
19467 16
19468 }
19469 }
19470
19471 unsafe impl
19472 fidl::encoding::Encode<
19473 BufferCollectionAttachTokenRequest,
19474 fidl::encoding::DefaultFuchsiaResourceDialect,
19475 > for &mut BufferCollectionAttachTokenRequest
19476 {
19477 unsafe fn encode(
19478 self,
19479 encoder: &mut fidl::encoding::Encoder<
19480 '_,
19481 fidl::encoding::DefaultFuchsiaResourceDialect,
19482 >,
19483 offset: usize,
19484 mut depth: fidl::encoding::Depth,
19485 ) -> fidl::Result<()> {
19486 encoder.debug_check_bounds::<BufferCollectionAttachTokenRequest>(offset);
19487 // Vector header
19488 let max_ordinal: u64 = self.max_ordinal_present();
19489 encoder.write_num(max_ordinal, offset);
19490 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
19491 // Calling encoder.out_of_line_offset(0) is not allowed.
19492 if max_ordinal == 0 {
19493 return Ok(());
19494 }
19495 depth.increment()?;
19496 let envelope_size = 8;
19497 let bytes_len = max_ordinal as usize * envelope_size;
19498 #[allow(unused_variables)]
19499 let offset = encoder.out_of_line_offset(bytes_len);
19500 let mut _prev_end_offset: usize = 0;
19501 if 1 > max_ordinal {
19502 return Ok(());
19503 }
19504
19505 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19506 // are envelope_size bytes.
19507 let cur_offset: usize = (1 - 1) * envelope_size;
19508
19509 // Zero reserved fields.
19510 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19511
19512 // Safety:
19513 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19514 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19515 // envelope_size bytes, there is always sufficient room.
19516 fidl::encoding::encode_in_envelope_optional::<
19517 fidl::Rights,
19518 fidl::encoding::DefaultFuchsiaResourceDialect,
19519 >(
19520 self.rights_attenuation_mask
19521 .as_ref()
19522 .map(<fidl::Rights as fidl::encoding::ValueTypeMarker>::borrow),
19523 encoder,
19524 offset + cur_offset,
19525 depth,
19526 )?;
19527
19528 _prev_end_offset = cur_offset + envelope_size;
19529 if 2 > max_ordinal {
19530 return Ok(());
19531 }
19532
19533 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19534 // are envelope_size bytes.
19535 let cur_offset: usize = (2 - 1) * envelope_size;
19536
19537 // Zero reserved fields.
19538 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19539
19540 // Safety:
19541 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19542 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19543 // envelope_size bytes, there is always sufficient room.
19544 fidl::encoding::encode_in_envelope_optional::<
19545 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
19546 fidl::encoding::DefaultFuchsiaResourceDialect,
19547 >(
19548 self.token_request.as_mut().map(
19549 <fidl::encoding::Endpoint<
19550 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
19551 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
19552 ),
19553 encoder,
19554 offset + cur_offset,
19555 depth,
19556 )?;
19557
19558 _prev_end_offset = cur_offset + envelope_size;
19559
19560 Ok(())
19561 }
19562 }
19563
19564 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
19565 for BufferCollectionAttachTokenRequest
19566 {
19567 #[inline(always)]
19568 fn new_empty() -> Self {
19569 Self::default()
19570 }
19571
19572 unsafe fn decode(
19573 &mut self,
19574 decoder: &mut fidl::encoding::Decoder<
19575 '_,
19576 fidl::encoding::DefaultFuchsiaResourceDialect,
19577 >,
19578 offset: usize,
19579 mut depth: fidl::encoding::Depth,
19580 ) -> fidl::Result<()> {
19581 decoder.debug_check_bounds::<Self>(offset);
19582 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
19583 None => return Err(fidl::Error::NotNullable),
19584 Some(len) => len,
19585 };
19586 // Calling decoder.out_of_line_offset(0) is not allowed.
19587 if len == 0 {
19588 return Ok(());
19589 };
19590 depth.increment()?;
19591 let envelope_size = 8;
19592 let bytes_len = len * envelope_size;
19593 let offset = decoder.out_of_line_offset(bytes_len)?;
19594 // Decode the envelope for each type.
19595 let mut _next_ordinal_to_read = 0;
19596 let mut next_offset = offset;
19597 let end_offset = offset + bytes_len;
19598 _next_ordinal_to_read += 1;
19599 if next_offset >= end_offset {
19600 return Ok(());
19601 }
19602
19603 // Decode unknown envelopes for gaps in ordinals.
19604 while _next_ordinal_to_read < 1 {
19605 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19606 _next_ordinal_to_read += 1;
19607 next_offset += envelope_size;
19608 }
19609
19610 let next_out_of_line = decoder.next_out_of_line();
19611 let handles_before = decoder.remaining_handles();
19612 if let Some((inlined, num_bytes, num_handles)) =
19613 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19614 {
19615 let member_inline_size =
19616 <fidl::Rights as fidl::encoding::TypeMarker>::inline_size(decoder.context);
19617 if inlined != (member_inline_size <= 4) {
19618 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19619 }
19620 let inner_offset;
19621 let mut inner_depth = depth.clone();
19622 if inlined {
19623 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19624 inner_offset = next_offset;
19625 } else {
19626 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19627 inner_depth.increment()?;
19628 }
19629 let val_ref = self.rights_attenuation_mask.get_or_insert_with(|| {
19630 fidl::new_empty!(fidl::Rights, fidl::encoding::DefaultFuchsiaResourceDialect)
19631 });
19632 fidl::decode!(
19633 fidl::Rights,
19634 fidl::encoding::DefaultFuchsiaResourceDialect,
19635 val_ref,
19636 decoder,
19637 inner_offset,
19638 inner_depth
19639 )?;
19640 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19641 {
19642 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19643 }
19644 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19645 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19646 }
19647 }
19648
19649 next_offset += envelope_size;
19650 _next_ordinal_to_read += 1;
19651 if next_offset >= end_offset {
19652 return Ok(());
19653 }
19654
19655 // Decode unknown envelopes for gaps in ordinals.
19656 while _next_ordinal_to_read < 2 {
19657 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19658 _next_ordinal_to_read += 1;
19659 next_offset += envelope_size;
19660 }
19661
19662 let next_out_of_line = decoder.next_out_of_line();
19663 let handles_before = decoder.remaining_handles();
19664 if let Some((inlined, num_bytes, num_handles)) =
19665 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19666 {
19667 let member_inline_size = <fidl::encoding::Endpoint<
19668 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
19669 > as fidl::encoding::TypeMarker>::inline_size(
19670 decoder.context
19671 );
19672 if inlined != (member_inline_size <= 4) {
19673 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19674 }
19675 let inner_offset;
19676 let mut inner_depth = depth.clone();
19677 if inlined {
19678 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19679 inner_offset = next_offset;
19680 } else {
19681 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19682 inner_depth.increment()?;
19683 }
19684 let val_ref = self.token_request.get_or_insert_with(|| {
19685 fidl::new_empty!(
19686 fidl::encoding::Endpoint<
19687 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
19688 >,
19689 fidl::encoding::DefaultFuchsiaResourceDialect
19690 )
19691 });
19692 fidl::decode!(
19693 fidl::encoding::Endpoint<
19694 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
19695 >,
19696 fidl::encoding::DefaultFuchsiaResourceDialect,
19697 val_ref,
19698 decoder,
19699 inner_offset,
19700 inner_depth
19701 )?;
19702 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19703 {
19704 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19705 }
19706 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19707 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19708 }
19709 }
19710
19711 next_offset += envelope_size;
19712
19713 // Decode the remaining unknown envelopes.
19714 while next_offset < end_offset {
19715 _next_ordinal_to_read += 1;
19716 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19717 next_offset += envelope_size;
19718 }
19719
19720 Ok(())
19721 }
19722 }
19723
19724 impl BufferCollectionInfo {
19725 #[inline(always)]
19726 fn max_ordinal_present(&self) -> u64 {
19727 if let Some(_) = self.buffer_collection_id {
19728 return 3;
19729 }
19730 if let Some(_) = self.buffers {
19731 return 2;
19732 }
19733 if let Some(_) = self.settings {
19734 return 1;
19735 }
19736 0
19737 }
19738 }
19739
19740 impl fidl::encoding::ResourceTypeMarker for BufferCollectionInfo {
19741 type Borrowed<'a> = &'a mut Self;
19742 fn take_or_borrow<'a>(
19743 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
19744 ) -> Self::Borrowed<'a> {
19745 value
19746 }
19747 }
19748
19749 unsafe impl fidl::encoding::TypeMarker for BufferCollectionInfo {
19750 type Owned = Self;
19751
19752 #[inline(always)]
19753 fn inline_align(_context: fidl::encoding::Context) -> usize {
19754 8
19755 }
19756
19757 #[inline(always)]
19758 fn inline_size(_context: fidl::encoding::Context) -> usize {
19759 16
19760 }
19761 }
19762
19763 unsafe impl
19764 fidl::encoding::Encode<BufferCollectionInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
19765 for &mut BufferCollectionInfo
19766 {
19767 unsafe fn encode(
19768 self,
19769 encoder: &mut fidl::encoding::Encoder<
19770 '_,
19771 fidl::encoding::DefaultFuchsiaResourceDialect,
19772 >,
19773 offset: usize,
19774 mut depth: fidl::encoding::Depth,
19775 ) -> fidl::Result<()> {
19776 encoder.debug_check_bounds::<BufferCollectionInfo>(offset);
19777 // Vector header
19778 let max_ordinal: u64 = self.max_ordinal_present();
19779 encoder.write_num(max_ordinal, offset);
19780 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
19781 // Calling encoder.out_of_line_offset(0) is not allowed.
19782 if max_ordinal == 0 {
19783 return Ok(());
19784 }
19785 depth.increment()?;
19786 let envelope_size = 8;
19787 let bytes_len = max_ordinal as usize * envelope_size;
19788 #[allow(unused_variables)]
19789 let offset = encoder.out_of_line_offset(bytes_len);
19790 let mut _prev_end_offset: usize = 0;
19791 if 1 > max_ordinal {
19792 return Ok(());
19793 }
19794
19795 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19796 // are envelope_size bytes.
19797 let cur_offset: usize = (1 - 1) * envelope_size;
19798
19799 // Zero reserved fields.
19800 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19801
19802 // Safety:
19803 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19804 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19805 // envelope_size bytes, there is always sufficient room.
19806 fidl::encoding::encode_in_envelope_optional::<
19807 SingleBufferSettings,
19808 fidl::encoding::DefaultFuchsiaResourceDialect,
19809 >(
19810 self.settings
19811 .as_ref()
19812 .map(<SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow),
19813 encoder,
19814 offset + cur_offset,
19815 depth,
19816 )?;
19817
19818 _prev_end_offset = cur_offset + envelope_size;
19819 if 2 > max_ordinal {
19820 return Ok(());
19821 }
19822
19823 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19824 // are envelope_size bytes.
19825 let cur_offset: usize = (2 - 1) * envelope_size;
19826
19827 // Zero reserved fields.
19828 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19829
19830 // Safety:
19831 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19832 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19833 // envelope_size bytes, there is always sufficient room.
19834 fidl::encoding::encode_in_envelope_optional::<fidl::encoding::Vector<VmoBuffer, 128>, fidl::encoding::DefaultFuchsiaResourceDialect>(
19835 self.buffers.as_mut().map(<fidl::encoding::Vector<VmoBuffer, 128> as fidl::encoding::ResourceTypeMarker>::take_or_borrow),
19836 encoder, offset + cur_offset, depth
19837 )?;
19838
19839 _prev_end_offset = cur_offset + envelope_size;
19840 if 3 > max_ordinal {
19841 return Ok(());
19842 }
19843
19844 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
19845 // are envelope_size bytes.
19846 let cur_offset: usize = (3 - 1) * envelope_size;
19847
19848 // Zero reserved fields.
19849 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
19850
19851 // Safety:
19852 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
19853 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
19854 // envelope_size bytes, there is always sufficient room.
19855 fidl::encoding::encode_in_envelope_optional::<
19856 u64,
19857 fidl::encoding::DefaultFuchsiaResourceDialect,
19858 >(
19859 self.buffer_collection_id
19860 .as_ref()
19861 .map(<u64 as fidl::encoding::ValueTypeMarker>::borrow),
19862 encoder,
19863 offset + cur_offset,
19864 depth,
19865 )?;
19866
19867 _prev_end_offset = cur_offset + envelope_size;
19868
19869 Ok(())
19870 }
19871 }
19872
19873 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
19874 for BufferCollectionInfo
19875 {
19876 #[inline(always)]
19877 fn new_empty() -> Self {
19878 Self::default()
19879 }
19880
19881 unsafe fn decode(
19882 &mut self,
19883 decoder: &mut fidl::encoding::Decoder<
19884 '_,
19885 fidl::encoding::DefaultFuchsiaResourceDialect,
19886 >,
19887 offset: usize,
19888 mut depth: fidl::encoding::Depth,
19889 ) -> fidl::Result<()> {
19890 decoder.debug_check_bounds::<Self>(offset);
19891 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
19892 None => return Err(fidl::Error::NotNullable),
19893 Some(len) => len,
19894 };
19895 // Calling decoder.out_of_line_offset(0) is not allowed.
19896 if len == 0 {
19897 return Ok(());
19898 };
19899 depth.increment()?;
19900 let envelope_size = 8;
19901 let bytes_len = len * envelope_size;
19902 let offset = decoder.out_of_line_offset(bytes_len)?;
19903 // Decode the envelope for each type.
19904 let mut _next_ordinal_to_read = 0;
19905 let mut next_offset = offset;
19906 let end_offset = offset + bytes_len;
19907 _next_ordinal_to_read += 1;
19908 if next_offset >= end_offset {
19909 return Ok(());
19910 }
19911
19912 // Decode unknown envelopes for gaps in ordinals.
19913 while _next_ordinal_to_read < 1 {
19914 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19915 _next_ordinal_to_read += 1;
19916 next_offset += envelope_size;
19917 }
19918
19919 let next_out_of_line = decoder.next_out_of_line();
19920 let handles_before = decoder.remaining_handles();
19921 if let Some((inlined, num_bytes, num_handles)) =
19922 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19923 {
19924 let member_inline_size =
19925 <SingleBufferSettings as fidl::encoding::TypeMarker>::inline_size(
19926 decoder.context,
19927 );
19928 if inlined != (member_inline_size <= 4) {
19929 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19930 }
19931 let inner_offset;
19932 let mut inner_depth = depth.clone();
19933 if inlined {
19934 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19935 inner_offset = next_offset;
19936 } else {
19937 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19938 inner_depth.increment()?;
19939 }
19940 let val_ref = self.settings.get_or_insert_with(|| {
19941 fidl::new_empty!(
19942 SingleBufferSettings,
19943 fidl::encoding::DefaultFuchsiaResourceDialect
19944 )
19945 });
19946 fidl::decode!(
19947 SingleBufferSettings,
19948 fidl::encoding::DefaultFuchsiaResourceDialect,
19949 val_ref,
19950 decoder,
19951 inner_offset,
19952 inner_depth
19953 )?;
19954 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19955 {
19956 return Err(fidl::Error::InvalidNumBytesInEnvelope);
19957 }
19958 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
19959 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
19960 }
19961 }
19962
19963 next_offset += envelope_size;
19964 _next_ordinal_to_read += 1;
19965 if next_offset >= end_offset {
19966 return Ok(());
19967 }
19968
19969 // Decode unknown envelopes for gaps in ordinals.
19970 while _next_ordinal_to_read < 2 {
19971 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
19972 _next_ordinal_to_read += 1;
19973 next_offset += envelope_size;
19974 }
19975
19976 let next_out_of_line = decoder.next_out_of_line();
19977 let handles_before = decoder.remaining_handles();
19978 if let Some((inlined, num_bytes, num_handles)) =
19979 fidl::encoding::decode_envelope_header(decoder, next_offset)?
19980 {
19981 let member_inline_size = <fidl::encoding::Vector<VmoBuffer, 128> as fidl::encoding::TypeMarker>::inline_size(decoder.context);
19982 if inlined != (member_inline_size <= 4) {
19983 return Err(fidl::Error::InvalidInlineBitInEnvelope);
19984 }
19985 let inner_offset;
19986 let mut inner_depth = depth.clone();
19987 if inlined {
19988 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
19989 inner_offset = next_offset;
19990 } else {
19991 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
19992 inner_depth.increment()?;
19993 }
19994 let val_ref =
19995 self.buffers.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::Vector<VmoBuffer, 128>, fidl::encoding::DefaultFuchsiaResourceDialect));
19996 fidl::decode!(fidl::encoding::Vector<VmoBuffer, 128>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
19997 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
19998 {
19999 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20000 }
20001 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20002 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20003 }
20004 }
20005
20006 next_offset += envelope_size;
20007 _next_ordinal_to_read += 1;
20008 if next_offset >= end_offset {
20009 return Ok(());
20010 }
20011
20012 // Decode unknown envelopes for gaps in ordinals.
20013 while _next_ordinal_to_read < 3 {
20014 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20015 _next_ordinal_to_read += 1;
20016 next_offset += envelope_size;
20017 }
20018
20019 let next_out_of_line = decoder.next_out_of_line();
20020 let handles_before = decoder.remaining_handles();
20021 if let Some((inlined, num_bytes, num_handles)) =
20022 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20023 {
20024 let member_inline_size =
20025 <u64 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
20026 if inlined != (member_inline_size <= 4) {
20027 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20028 }
20029 let inner_offset;
20030 let mut inner_depth = depth.clone();
20031 if inlined {
20032 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20033 inner_offset = next_offset;
20034 } else {
20035 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20036 inner_depth.increment()?;
20037 }
20038 let val_ref = self.buffer_collection_id.get_or_insert_with(|| {
20039 fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect)
20040 });
20041 fidl::decode!(
20042 u64,
20043 fidl::encoding::DefaultFuchsiaResourceDialect,
20044 val_ref,
20045 decoder,
20046 inner_offset,
20047 inner_depth
20048 )?;
20049 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20050 {
20051 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20052 }
20053 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20054 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20055 }
20056 }
20057
20058 next_offset += envelope_size;
20059
20060 // Decode the remaining unknown envelopes.
20061 while next_offset < end_offset {
20062 _next_ordinal_to_read += 1;
20063 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20064 next_offset += envelope_size;
20065 }
20066
20067 Ok(())
20068 }
20069 }
20070
20071 impl BufferCollectionSetConstraintsRequest {
20072 #[inline(always)]
20073 fn max_ordinal_present(&self) -> u64 {
20074 if let Some(_) = self.must_match_vmo {
20075 return 2;
20076 }
20077 if let Some(_) = self.constraints {
20078 return 1;
20079 }
20080 0
20081 }
20082 }
20083
20084 impl fidl::encoding::ResourceTypeMarker for BufferCollectionSetConstraintsRequest {
20085 type Borrowed<'a> = &'a mut Self;
20086 fn take_or_borrow<'a>(
20087 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
20088 ) -> Self::Borrowed<'a> {
20089 value
20090 }
20091 }
20092
20093 unsafe impl fidl::encoding::TypeMarker for BufferCollectionSetConstraintsRequest {
20094 type Owned = Self;
20095
20096 #[inline(always)]
20097 fn inline_align(_context: fidl::encoding::Context) -> usize {
20098 8
20099 }
20100
20101 #[inline(always)]
20102 fn inline_size(_context: fidl::encoding::Context) -> usize {
20103 16
20104 }
20105 }
20106
20107 unsafe impl
20108 fidl::encoding::Encode<
20109 BufferCollectionSetConstraintsRequest,
20110 fidl::encoding::DefaultFuchsiaResourceDialect,
20111 > for &mut BufferCollectionSetConstraintsRequest
20112 {
20113 unsafe fn encode(
20114 self,
20115 encoder: &mut fidl::encoding::Encoder<
20116 '_,
20117 fidl::encoding::DefaultFuchsiaResourceDialect,
20118 >,
20119 offset: usize,
20120 mut depth: fidl::encoding::Depth,
20121 ) -> fidl::Result<()> {
20122 encoder.debug_check_bounds::<BufferCollectionSetConstraintsRequest>(offset);
20123 // Vector header
20124 let max_ordinal: u64 = self.max_ordinal_present();
20125 encoder.write_num(max_ordinal, offset);
20126 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
20127 // Calling encoder.out_of_line_offset(0) is not allowed.
20128 if max_ordinal == 0 {
20129 return Ok(());
20130 }
20131 depth.increment()?;
20132 let envelope_size = 8;
20133 let bytes_len = max_ordinal as usize * envelope_size;
20134 #[allow(unused_variables)]
20135 let offset = encoder.out_of_line_offset(bytes_len);
20136 let mut _prev_end_offset: usize = 0;
20137 if 1 > max_ordinal {
20138 return Ok(());
20139 }
20140
20141 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20142 // are envelope_size bytes.
20143 let cur_offset: usize = (1 - 1) * envelope_size;
20144
20145 // Zero reserved fields.
20146 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20147
20148 // Safety:
20149 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20150 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20151 // envelope_size bytes, there is always sufficient room.
20152 fidl::encoding::encode_in_envelope_optional::<
20153 BufferCollectionConstraints,
20154 fidl::encoding::DefaultFuchsiaResourceDialect,
20155 >(
20156 self.constraints
20157 .as_ref()
20158 .map(<BufferCollectionConstraints as fidl::encoding::ValueTypeMarker>::borrow),
20159 encoder,
20160 offset + cur_offset,
20161 depth,
20162 )?;
20163
20164 _prev_end_offset = cur_offset + envelope_size;
20165 if 2 > max_ordinal {
20166 return Ok(());
20167 }
20168
20169 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20170 // are envelope_size bytes.
20171 let cur_offset: usize = (2 - 1) * envelope_size;
20172
20173 // Zero reserved fields.
20174 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20175
20176 // Safety:
20177 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20178 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20179 // envelope_size bytes, there is always sufficient room.
20180 fidl::encoding::encode_in_envelope_optional::<
20181 fidl::encoding::HandleType<
20182 fidl::Vmo,
20183 { fidl::ObjectType::VMO.into_raw() },
20184 2147483648,
20185 >,
20186 fidl::encoding::DefaultFuchsiaResourceDialect,
20187 >(
20188 self.must_match_vmo.as_mut().map(
20189 <fidl::encoding::HandleType<
20190 fidl::Vmo,
20191 { fidl::ObjectType::VMO.into_raw() },
20192 2147483648,
20193 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
20194 ),
20195 encoder,
20196 offset + cur_offset,
20197 depth,
20198 )?;
20199
20200 _prev_end_offset = cur_offset + envelope_size;
20201
20202 Ok(())
20203 }
20204 }
20205
20206 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
20207 for BufferCollectionSetConstraintsRequest
20208 {
20209 #[inline(always)]
20210 fn new_empty() -> Self {
20211 Self::default()
20212 }
20213
20214 unsafe fn decode(
20215 &mut self,
20216 decoder: &mut fidl::encoding::Decoder<
20217 '_,
20218 fidl::encoding::DefaultFuchsiaResourceDialect,
20219 >,
20220 offset: usize,
20221 mut depth: fidl::encoding::Depth,
20222 ) -> fidl::Result<()> {
20223 decoder.debug_check_bounds::<Self>(offset);
20224 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
20225 None => return Err(fidl::Error::NotNullable),
20226 Some(len) => len,
20227 };
20228 // Calling decoder.out_of_line_offset(0) is not allowed.
20229 if len == 0 {
20230 return Ok(());
20231 };
20232 depth.increment()?;
20233 let envelope_size = 8;
20234 let bytes_len = len * envelope_size;
20235 let offset = decoder.out_of_line_offset(bytes_len)?;
20236 // Decode the envelope for each type.
20237 let mut _next_ordinal_to_read = 0;
20238 let mut next_offset = offset;
20239 let end_offset = offset + bytes_len;
20240 _next_ordinal_to_read += 1;
20241 if next_offset >= end_offset {
20242 return Ok(());
20243 }
20244
20245 // Decode unknown envelopes for gaps in ordinals.
20246 while _next_ordinal_to_read < 1 {
20247 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20248 _next_ordinal_to_read += 1;
20249 next_offset += envelope_size;
20250 }
20251
20252 let next_out_of_line = decoder.next_out_of_line();
20253 let handles_before = decoder.remaining_handles();
20254 if let Some((inlined, num_bytes, num_handles)) =
20255 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20256 {
20257 let member_inline_size =
20258 <BufferCollectionConstraints as fidl::encoding::TypeMarker>::inline_size(
20259 decoder.context,
20260 );
20261 if inlined != (member_inline_size <= 4) {
20262 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20263 }
20264 let inner_offset;
20265 let mut inner_depth = depth.clone();
20266 if inlined {
20267 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20268 inner_offset = next_offset;
20269 } else {
20270 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20271 inner_depth.increment()?;
20272 }
20273 let val_ref = self.constraints.get_or_insert_with(|| {
20274 fidl::new_empty!(
20275 BufferCollectionConstraints,
20276 fidl::encoding::DefaultFuchsiaResourceDialect
20277 )
20278 });
20279 fidl::decode!(
20280 BufferCollectionConstraints,
20281 fidl::encoding::DefaultFuchsiaResourceDialect,
20282 val_ref,
20283 decoder,
20284 inner_offset,
20285 inner_depth
20286 )?;
20287 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20288 {
20289 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20290 }
20291 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20292 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20293 }
20294 }
20295
20296 next_offset += envelope_size;
20297 _next_ordinal_to_read += 1;
20298 if next_offset >= end_offset {
20299 return Ok(());
20300 }
20301
20302 // Decode unknown envelopes for gaps in ordinals.
20303 while _next_ordinal_to_read < 2 {
20304 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20305 _next_ordinal_to_read += 1;
20306 next_offset += envelope_size;
20307 }
20308
20309 let next_out_of_line = decoder.next_out_of_line();
20310 let handles_before = decoder.remaining_handles();
20311 if let Some((inlined, num_bytes, num_handles)) =
20312 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20313 {
20314 let member_inline_size = <fidl::encoding::HandleType<
20315 fidl::Vmo,
20316 { fidl::ObjectType::VMO.into_raw() },
20317 2147483648,
20318 > as fidl::encoding::TypeMarker>::inline_size(
20319 decoder.context
20320 );
20321 if inlined != (member_inline_size <= 4) {
20322 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20323 }
20324 let inner_offset;
20325 let mut inner_depth = depth.clone();
20326 if inlined {
20327 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20328 inner_offset = next_offset;
20329 } else {
20330 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20331 inner_depth.increment()?;
20332 }
20333 let val_ref =
20334 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));
20335 fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
20336 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20337 {
20338 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20339 }
20340 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20341 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20342 }
20343 }
20344
20345 next_offset += envelope_size;
20346
20347 // Decode the remaining unknown envelopes.
20348 while next_offset < end_offset {
20349 _next_ordinal_to_read += 1;
20350 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20351 next_offset += envelope_size;
20352 }
20353
20354 Ok(())
20355 }
20356 }
20357
20358 impl BufferCollectionTokenCreateBufferCollectionTokenGroupRequest {
20359 #[inline(always)]
20360 fn max_ordinal_present(&self) -> u64 {
20361 if let Some(_) = self.group_request {
20362 return 1;
20363 }
20364 0
20365 }
20366 }
20367
20368 impl fidl::encoding::ResourceTypeMarker
20369 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
20370 {
20371 type Borrowed<'a> = &'a mut Self;
20372 fn take_or_borrow<'a>(
20373 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
20374 ) -> Self::Borrowed<'a> {
20375 value
20376 }
20377 }
20378
20379 unsafe impl fidl::encoding::TypeMarker
20380 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
20381 {
20382 type Owned = Self;
20383
20384 #[inline(always)]
20385 fn inline_align(_context: fidl::encoding::Context) -> usize {
20386 8
20387 }
20388
20389 #[inline(always)]
20390 fn inline_size(_context: fidl::encoding::Context) -> usize {
20391 16
20392 }
20393 }
20394
20395 unsafe impl
20396 fidl::encoding::Encode<
20397 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
20398 fidl::encoding::DefaultFuchsiaResourceDialect,
20399 > for &mut BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
20400 {
20401 unsafe fn encode(
20402 self,
20403 encoder: &mut fidl::encoding::Encoder<
20404 '_,
20405 fidl::encoding::DefaultFuchsiaResourceDialect,
20406 >,
20407 offset: usize,
20408 mut depth: fidl::encoding::Depth,
20409 ) -> fidl::Result<()> {
20410 encoder
20411 .debug_check_bounds::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
20412 offset,
20413 );
20414 // Vector header
20415 let max_ordinal: u64 = self.max_ordinal_present();
20416 encoder.write_num(max_ordinal, offset);
20417 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
20418 // Calling encoder.out_of_line_offset(0) is not allowed.
20419 if max_ordinal == 0 {
20420 return Ok(());
20421 }
20422 depth.increment()?;
20423 let envelope_size = 8;
20424 let bytes_len = max_ordinal as usize * envelope_size;
20425 #[allow(unused_variables)]
20426 let offset = encoder.out_of_line_offset(bytes_len);
20427 let mut _prev_end_offset: usize = 0;
20428 if 1 > max_ordinal {
20429 return Ok(());
20430 }
20431
20432 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20433 // are envelope_size bytes.
20434 let cur_offset: usize = (1 - 1) * envelope_size;
20435
20436 // Zero reserved fields.
20437 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20438
20439 // Safety:
20440 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20441 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20442 // envelope_size bytes, there is always sufficient room.
20443 fidl::encoding::encode_in_envelope_optional::<
20444 fidl::encoding::Endpoint<
20445 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
20446 >,
20447 fidl::encoding::DefaultFuchsiaResourceDialect,
20448 >(
20449 self.group_request.as_mut().map(
20450 <fidl::encoding::Endpoint<
20451 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
20452 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
20453 ),
20454 encoder,
20455 offset + cur_offset,
20456 depth,
20457 )?;
20458
20459 _prev_end_offset = cur_offset + envelope_size;
20460
20461 Ok(())
20462 }
20463 }
20464
20465 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
20466 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
20467 {
20468 #[inline(always)]
20469 fn new_empty() -> Self {
20470 Self::default()
20471 }
20472
20473 unsafe fn decode(
20474 &mut self,
20475 decoder: &mut fidl::encoding::Decoder<
20476 '_,
20477 fidl::encoding::DefaultFuchsiaResourceDialect,
20478 >,
20479 offset: usize,
20480 mut depth: fidl::encoding::Depth,
20481 ) -> fidl::Result<()> {
20482 decoder.debug_check_bounds::<Self>(offset);
20483 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
20484 None => return Err(fidl::Error::NotNullable),
20485 Some(len) => len,
20486 };
20487 // Calling decoder.out_of_line_offset(0) is not allowed.
20488 if len == 0 {
20489 return Ok(());
20490 };
20491 depth.increment()?;
20492 let envelope_size = 8;
20493 let bytes_len = len * envelope_size;
20494 let offset = decoder.out_of_line_offset(bytes_len)?;
20495 // Decode the envelope for each type.
20496 let mut _next_ordinal_to_read = 0;
20497 let mut next_offset = offset;
20498 let end_offset = offset + bytes_len;
20499 _next_ordinal_to_read += 1;
20500 if next_offset >= end_offset {
20501 return Ok(());
20502 }
20503
20504 // Decode unknown envelopes for gaps in ordinals.
20505 while _next_ordinal_to_read < 1 {
20506 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20507 _next_ordinal_to_read += 1;
20508 next_offset += envelope_size;
20509 }
20510
20511 let next_out_of_line = decoder.next_out_of_line();
20512 let handles_before = decoder.remaining_handles();
20513 if let Some((inlined, num_bytes, num_handles)) =
20514 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20515 {
20516 let member_inline_size = <fidl::encoding::Endpoint<
20517 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
20518 > as fidl::encoding::TypeMarker>::inline_size(
20519 decoder.context
20520 );
20521 if inlined != (member_inline_size <= 4) {
20522 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20523 }
20524 let inner_offset;
20525 let mut inner_depth = depth.clone();
20526 if inlined {
20527 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20528 inner_offset = next_offset;
20529 } else {
20530 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20531 inner_depth.increment()?;
20532 }
20533 let val_ref = self.group_request.get_or_insert_with(|| {
20534 fidl::new_empty!(
20535 fidl::encoding::Endpoint<
20536 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
20537 >,
20538 fidl::encoding::DefaultFuchsiaResourceDialect
20539 )
20540 });
20541 fidl::decode!(
20542 fidl::encoding::Endpoint<
20543 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
20544 >,
20545 fidl::encoding::DefaultFuchsiaResourceDialect,
20546 val_ref,
20547 decoder,
20548 inner_offset,
20549 inner_depth
20550 )?;
20551 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20552 {
20553 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20554 }
20555 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20556 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20557 }
20558 }
20559
20560 next_offset += envelope_size;
20561
20562 // Decode the remaining unknown envelopes.
20563 while next_offset < end_offset {
20564 _next_ordinal_to_read += 1;
20565 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20566 next_offset += envelope_size;
20567 }
20568
20569 Ok(())
20570 }
20571 }
20572
20573 impl BufferCollectionTokenDuplicateRequest {
20574 #[inline(always)]
20575 fn max_ordinal_present(&self) -> u64 {
20576 if let Some(_) = self.token_request {
20577 return 2;
20578 }
20579 if let Some(_) = self.rights_attenuation_mask {
20580 return 1;
20581 }
20582 0
20583 }
20584 }
20585
20586 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateRequest {
20587 type Borrowed<'a> = &'a mut Self;
20588 fn take_or_borrow<'a>(
20589 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
20590 ) -> Self::Borrowed<'a> {
20591 value
20592 }
20593 }
20594
20595 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateRequest {
20596 type Owned = Self;
20597
20598 #[inline(always)]
20599 fn inline_align(_context: fidl::encoding::Context) -> usize {
20600 8
20601 }
20602
20603 #[inline(always)]
20604 fn inline_size(_context: fidl::encoding::Context) -> usize {
20605 16
20606 }
20607 }
20608
20609 unsafe impl
20610 fidl::encoding::Encode<
20611 BufferCollectionTokenDuplicateRequest,
20612 fidl::encoding::DefaultFuchsiaResourceDialect,
20613 > for &mut BufferCollectionTokenDuplicateRequest
20614 {
20615 unsafe fn encode(
20616 self,
20617 encoder: &mut fidl::encoding::Encoder<
20618 '_,
20619 fidl::encoding::DefaultFuchsiaResourceDialect,
20620 >,
20621 offset: usize,
20622 mut depth: fidl::encoding::Depth,
20623 ) -> fidl::Result<()> {
20624 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateRequest>(offset);
20625 // Vector header
20626 let max_ordinal: u64 = self.max_ordinal_present();
20627 encoder.write_num(max_ordinal, offset);
20628 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
20629 // Calling encoder.out_of_line_offset(0) is not allowed.
20630 if max_ordinal == 0 {
20631 return Ok(());
20632 }
20633 depth.increment()?;
20634 let envelope_size = 8;
20635 let bytes_len = max_ordinal as usize * envelope_size;
20636 #[allow(unused_variables)]
20637 let offset = encoder.out_of_line_offset(bytes_len);
20638 let mut _prev_end_offset: usize = 0;
20639 if 1 > max_ordinal {
20640 return Ok(());
20641 }
20642
20643 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20644 // are envelope_size bytes.
20645 let cur_offset: usize = (1 - 1) * envelope_size;
20646
20647 // Zero reserved fields.
20648 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20649
20650 // Safety:
20651 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20652 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20653 // envelope_size bytes, there is always sufficient room.
20654 fidl::encoding::encode_in_envelope_optional::<
20655 fidl::Rights,
20656 fidl::encoding::DefaultFuchsiaResourceDialect,
20657 >(
20658 self.rights_attenuation_mask
20659 .as_ref()
20660 .map(<fidl::Rights as fidl::encoding::ValueTypeMarker>::borrow),
20661 encoder,
20662 offset + cur_offset,
20663 depth,
20664 )?;
20665
20666 _prev_end_offset = cur_offset + envelope_size;
20667 if 2 > max_ordinal {
20668 return Ok(());
20669 }
20670
20671 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20672 // are envelope_size bytes.
20673 let cur_offset: usize = (2 - 1) * envelope_size;
20674
20675 // Zero reserved fields.
20676 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20677
20678 // Safety:
20679 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20680 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20681 // envelope_size bytes, there is always sufficient room.
20682 fidl::encoding::encode_in_envelope_optional::<
20683 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
20684 fidl::encoding::DefaultFuchsiaResourceDialect,
20685 >(
20686 self.token_request.as_mut().map(
20687 <fidl::encoding::Endpoint<
20688 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
20689 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
20690 ),
20691 encoder,
20692 offset + cur_offset,
20693 depth,
20694 )?;
20695
20696 _prev_end_offset = cur_offset + envelope_size;
20697
20698 Ok(())
20699 }
20700 }
20701
20702 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
20703 for BufferCollectionTokenDuplicateRequest
20704 {
20705 #[inline(always)]
20706 fn new_empty() -> Self {
20707 Self::default()
20708 }
20709
20710 unsafe fn decode(
20711 &mut self,
20712 decoder: &mut fidl::encoding::Decoder<
20713 '_,
20714 fidl::encoding::DefaultFuchsiaResourceDialect,
20715 >,
20716 offset: usize,
20717 mut depth: fidl::encoding::Depth,
20718 ) -> fidl::Result<()> {
20719 decoder.debug_check_bounds::<Self>(offset);
20720 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
20721 None => return Err(fidl::Error::NotNullable),
20722 Some(len) => len,
20723 };
20724 // Calling decoder.out_of_line_offset(0) is not allowed.
20725 if len == 0 {
20726 return Ok(());
20727 };
20728 depth.increment()?;
20729 let envelope_size = 8;
20730 let bytes_len = len * envelope_size;
20731 let offset = decoder.out_of_line_offset(bytes_len)?;
20732 // Decode the envelope for each type.
20733 let mut _next_ordinal_to_read = 0;
20734 let mut next_offset = offset;
20735 let end_offset = offset + bytes_len;
20736 _next_ordinal_to_read += 1;
20737 if next_offset >= end_offset {
20738 return Ok(());
20739 }
20740
20741 // Decode unknown envelopes for gaps in ordinals.
20742 while _next_ordinal_to_read < 1 {
20743 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20744 _next_ordinal_to_read += 1;
20745 next_offset += envelope_size;
20746 }
20747
20748 let next_out_of_line = decoder.next_out_of_line();
20749 let handles_before = decoder.remaining_handles();
20750 if let Some((inlined, num_bytes, num_handles)) =
20751 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20752 {
20753 let member_inline_size =
20754 <fidl::Rights as fidl::encoding::TypeMarker>::inline_size(decoder.context);
20755 if inlined != (member_inline_size <= 4) {
20756 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20757 }
20758 let inner_offset;
20759 let mut inner_depth = depth.clone();
20760 if inlined {
20761 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20762 inner_offset = next_offset;
20763 } else {
20764 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20765 inner_depth.increment()?;
20766 }
20767 let val_ref = self.rights_attenuation_mask.get_or_insert_with(|| {
20768 fidl::new_empty!(fidl::Rights, fidl::encoding::DefaultFuchsiaResourceDialect)
20769 });
20770 fidl::decode!(
20771 fidl::Rights,
20772 fidl::encoding::DefaultFuchsiaResourceDialect,
20773 val_ref,
20774 decoder,
20775 inner_offset,
20776 inner_depth
20777 )?;
20778 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20779 {
20780 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20781 }
20782 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20783 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20784 }
20785 }
20786
20787 next_offset += envelope_size;
20788 _next_ordinal_to_read += 1;
20789 if next_offset >= end_offset {
20790 return Ok(());
20791 }
20792
20793 // Decode unknown envelopes for gaps in ordinals.
20794 while _next_ordinal_to_read < 2 {
20795 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20796 _next_ordinal_to_read += 1;
20797 next_offset += envelope_size;
20798 }
20799
20800 let next_out_of_line = decoder.next_out_of_line();
20801 let handles_before = decoder.remaining_handles();
20802 if let Some((inlined, num_bytes, num_handles)) =
20803 fidl::encoding::decode_envelope_header(decoder, next_offset)?
20804 {
20805 let member_inline_size = <fidl::encoding::Endpoint<
20806 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
20807 > as fidl::encoding::TypeMarker>::inline_size(
20808 decoder.context
20809 );
20810 if inlined != (member_inline_size <= 4) {
20811 return Err(fidl::Error::InvalidInlineBitInEnvelope);
20812 }
20813 let inner_offset;
20814 let mut inner_depth = depth.clone();
20815 if inlined {
20816 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
20817 inner_offset = next_offset;
20818 } else {
20819 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
20820 inner_depth.increment()?;
20821 }
20822 let val_ref = self.token_request.get_or_insert_with(|| {
20823 fidl::new_empty!(
20824 fidl::encoding::Endpoint<
20825 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
20826 >,
20827 fidl::encoding::DefaultFuchsiaResourceDialect
20828 )
20829 });
20830 fidl::decode!(
20831 fidl::encoding::Endpoint<
20832 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
20833 >,
20834 fidl::encoding::DefaultFuchsiaResourceDialect,
20835 val_ref,
20836 decoder,
20837 inner_offset,
20838 inner_depth
20839 )?;
20840 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
20841 {
20842 return Err(fidl::Error::InvalidNumBytesInEnvelope);
20843 }
20844 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
20845 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
20846 }
20847 }
20848
20849 next_offset += envelope_size;
20850
20851 // Decode the remaining unknown envelopes.
20852 while next_offset < end_offset {
20853 _next_ordinal_to_read += 1;
20854 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
20855 next_offset += envelope_size;
20856 }
20857
20858 Ok(())
20859 }
20860 }
20861
20862 impl BufferCollectionTokenGroupCreateChildRequest {
20863 #[inline(always)]
20864 fn max_ordinal_present(&self) -> u64 {
20865 if let Some(_) = self.rights_attenuation_mask {
20866 return 2;
20867 }
20868 if let Some(_) = self.token_request {
20869 return 1;
20870 }
20871 0
20872 }
20873 }
20874
20875 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildRequest {
20876 type Borrowed<'a> = &'a mut Self;
20877 fn take_or_borrow<'a>(
20878 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
20879 ) -> Self::Borrowed<'a> {
20880 value
20881 }
20882 }
20883
20884 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildRequest {
20885 type Owned = Self;
20886
20887 #[inline(always)]
20888 fn inline_align(_context: fidl::encoding::Context) -> usize {
20889 8
20890 }
20891
20892 #[inline(always)]
20893 fn inline_size(_context: fidl::encoding::Context) -> usize {
20894 16
20895 }
20896 }
20897
20898 unsafe impl
20899 fidl::encoding::Encode<
20900 BufferCollectionTokenGroupCreateChildRequest,
20901 fidl::encoding::DefaultFuchsiaResourceDialect,
20902 > for &mut BufferCollectionTokenGroupCreateChildRequest
20903 {
20904 unsafe fn encode(
20905 self,
20906 encoder: &mut fidl::encoding::Encoder<
20907 '_,
20908 fidl::encoding::DefaultFuchsiaResourceDialect,
20909 >,
20910 offset: usize,
20911 mut depth: fidl::encoding::Depth,
20912 ) -> fidl::Result<()> {
20913 encoder.debug_check_bounds::<BufferCollectionTokenGroupCreateChildRequest>(offset);
20914 // Vector header
20915 let max_ordinal: u64 = self.max_ordinal_present();
20916 encoder.write_num(max_ordinal, offset);
20917 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
20918 // Calling encoder.out_of_line_offset(0) is not allowed.
20919 if max_ordinal == 0 {
20920 return Ok(());
20921 }
20922 depth.increment()?;
20923 let envelope_size = 8;
20924 let bytes_len = max_ordinal as usize * envelope_size;
20925 #[allow(unused_variables)]
20926 let offset = encoder.out_of_line_offset(bytes_len);
20927 let mut _prev_end_offset: usize = 0;
20928 if 1 > max_ordinal {
20929 return Ok(());
20930 }
20931
20932 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20933 // are envelope_size bytes.
20934 let cur_offset: usize = (1 - 1) * envelope_size;
20935
20936 // Zero reserved fields.
20937 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20938
20939 // Safety:
20940 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20941 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20942 // envelope_size bytes, there is always sufficient room.
20943 fidl::encoding::encode_in_envelope_optional::<
20944 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
20945 fidl::encoding::DefaultFuchsiaResourceDialect,
20946 >(
20947 self.token_request.as_mut().map(
20948 <fidl::encoding::Endpoint<
20949 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
20950 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
20951 ),
20952 encoder,
20953 offset + cur_offset,
20954 depth,
20955 )?;
20956
20957 _prev_end_offset = cur_offset + envelope_size;
20958 if 2 > max_ordinal {
20959 return Ok(());
20960 }
20961
20962 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
20963 // are envelope_size bytes.
20964 let cur_offset: usize = (2 - 1) * envelope_size;
20965
20966 // Zero reserved fields.
20967 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
20968
20969 // Safety:
20970 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
20971 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
20972 // envelope_size bytes, there is always sufficient room.
20973 fidl::encoding::encode_in_envelope_optional::<
20974 fidl::Rights,
20975 fidl::encoding::DefaultFuchsiaResourceDialect,
20976 >(
20977 self.rights_attenuation_mask
20978 .as_ref()
20979 .map(<fidl::Rights as fidl::encoding::ValueTypeMarker>::borrow),
20980 encoder,
20981 offset + cur_offset,
20982 depth,
20983 )?;
20984
20985 _prev_end_offset = cur_offset + envelope_size;
20986
20987 Ok(())
20988 }
20989 }
20990
20991 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
20992 for BufferCollectionTokenGroupCreateChildRequest
20993 {
20994 #[inline(always)]
20995 fn new_empty() -> Self {
20996 Self::default()
20997 }
20998
20999 unsafe fn decode(
21000 &mut self,
21001 decoder: &mut fidl::encoding::Decoder<
21002 '_,
21003 fidl::encoding::DefaultFuchsiaResourceDialect,
21004 >,
21005 offset: usize,
21006 mut depth: fidl::encoding::Depth,
21007 ) -> fidl::Result<()> {
21008 decoder.debug_check_bounds::<Self>(offset);
21009 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
21010 None => return Err(fidl::Error::NotNullable),
21011 Some(len) => len,
21012 };
21013 // Calling decoder.out_of_line_offset(0) is not allowed.
21014 if len == 0 {
21015 return Ok(());
21016 };
21017 depth.increment()?;
21018 let envelope_size = 8;
21019 let bytes_len = len * envelope_size;
21020 let offset = decoder.out_of_line_offset(bytes_len)?;
21021 // Decode the envelope for each type.
21022 let mut _next_ordinal_to_read = 0;
21023 let mut next_offset = offset;
21024 let end_offset = offset + bytes_len;
21025 _next_ordinal_to_read += 1;
21026 if next_offset >= end_offset {
21027 return Ok(());
21028 }
21029
21030 // Decode unknown envelopes for gaps in ordinals.
21031 while _next_ordinal_to_read < 1 {
21032 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21033 _next_ordinal_to_read += 1;
21034 next_offset += envelope_size;
21035 }
21036
21037 let next_out_of_line = decoder.next_out_of_line();
21038 let handles_before = decoder.remaining_handles();
21039 if let Some((inlined, num_bytes, num_handles)) =
21040 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21041 {
21042 let member_inline_size = <fidl::encoding::Endpoint<
21043 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
21044 > as fidl::encoding::TypeMarker>::inline_size(
21045 decoder.context
21046 );
21047 if inlined != (member_inline_size <= 4) {
21048 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21049 }
21050 let inner_offset;
21051 let mut inner_depth = depth.clone();
21052 if inlined {
21053 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21054 inner_offset = next_offset;
21055 } else {
21056 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21057 inner_depth.increment()?;
21058 }
21059 let val_ref = self.token_request.get_or_insert_with(|| {
21060 fidl::new_empty!(
21061 fidl::encoding::Endpoint<
21062 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
21063 >,
21064 fidl::encoding::DefaultFuchsiaResourceDialect
21065 )
21066 });
21067 fidl::decode!(
21068 fidl::encoding::Endpoint<
21069 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
21070 >,
21071 fidl::encoding::DefaultFuchsiaResourceDialect,
21072 val_ref,
21073 decoder,
21074 inner_offset,
21075 inner_depth
21076 )?;
21077 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21078 {
21079 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21080 }
21081 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21082 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21083 }
21084 }
21085
21086 next_offset += envelope_size;
21087 _next_ordinal_to_read += 1;
21088 if next_offset >= end_offset {
21089 return Ok(());
21090 }
21091
21092 // Decode unknown envelopes for gaps in ordinals.
21093 while _next_ordinal_to_read < 2 {
21094 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21095 _next_ordinal_to_read += 1;
21096 next_offset += envelope_size;
21097 }
21098
21099 let next_out_of_line = decoder.next_out_of_line();
21100 let handles_before = decoder.remaining_handles();
21101 if let Some((inlined, num_bytes, num_handles)) =
21102 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21103 {
21104 let member_inline_size =
21105 <fidl::Rights as fidl::encoding::TypeMarker>::inline_size(decoder.context);
21106 if inlined != (member_inline_size <= 4) {
21107 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21108 }
21109 let inner_offset;
21110 let mut inner_depth = depth.clone();
21111 if inlined {
21112 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21113 inner_offset = next_offset;
21114 } else {
21115 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21116 inner_depth.increment()?;
21117 }
21118 let val_ref = self.rights_attenuation_mask.get_or_insert_with(|| {
21119 fidl::new_empty!(fidl::Rights, fidl::encoding::DefaultFuchsiaResourceDialect)
21120 });
21121 fidl::decode!(
21122 fidl::Rights,
21123 fidl::encoding::DefaultFuchsiaResourceDialect,
21124 val_ref,
21125 decoder,
21126 inner_offset,
21127 inner_depth
21128 )?;
21129 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21130 {
21131 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21132 }
21133 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21134 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21135 }
21136 }
21137
21138 next_offset += envelope_size;
21139
21140 // Decode the remaining unknown envelopes.
21141 while next_offset < end_offset {
21142 _next_ordinal_to_read += 1;
21143 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21144 next_offset += envelope_size;
21145 }
21146
21147 Ok(())
21148 }
21149 }
21150
21151 impl BufferCollectionTokenGroupCreateChildrenSyncResponse {
21152 #[inline(always)]
21153 fn max_ordinal_present(&self) -> u64 {
21154 if let Some(_) = self.tokens {
21155 return 1;
21156 }
21157 0
21158 }
21159 }
21160
21161 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
21162 type Borrowed<'a> = &'a mut Self;
21163 fn take_or_borrow<'a>(
21164 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
21165 ) -> Self::Borrowed<'a> {
21166 value
21167 }
21168 }
21169
21170 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
21171 type Owned = Self;
21172
21173 #[inline(always)]
21174 fn inline_align(_context: fidl::encoding::Context) -> usize {
21175 8
21176 }
21177
21178 #[inline(always)]
21179 fn inline_size(_context: fidl::encoding::Context) -> usize {
21180 16
21181 }
21182 }
21183
21184 unsafe impl
21185 fidl::encoding::Encode<
21186 BufferCollectionTokenGroupCreateChildrenSyncResponse,
21187 fidl::encoding::DefaultFuchsiaResourceDialect,
21188 > for &mut BufferCollectionTokenGroupCreateChildrenSyncResponse
21189 {
21190 unsafe fn encode(
21191 self,
21192 encoder: &mut fidl::encoding::Encoder<
21193 '_,
21194 fidl::encoding::DefaultFuchsiaResourceDialect,
21195 >,
21196 offset: usize,
21197 mut depth: fidl::encoding::Depth,
21198 ) -> fidl::Result<()> {
21199 encoder
21200 .debug_check_bounds::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(offset);
21201 // Vector header
21202 let max_ordinal: u64 = self.max_ordinal_present();
21203 encoder.write_num(max_ordinal, offset);
21204 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
21205 // Calling encoder.out_of_line_offset(0) is not allowed.
21206 if max_ordinal == 0 {
21207 return Ok(());
21208 }
21209 depth.increment()?;
21210 let envelope_size = 8;
21211 let bytes_len = max_ordinal as usize * envelope_size;
21212 #[allow(unused_variables)]
21213 let offset = encoder.out_of_line_offset(bytes_len);
21214 let mut _prev_end_offset: usize = 0;
21215 if 1 > max_ordinal {
21216 return Ok(());
21217 }
21218
21219 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
21220 // are envelope_size bytes.
21221 let cur_offset: usize = (1 - 1) * envelope_size;
21222
21223 // Zero reserved fields.
21224 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
21225
21226 // Safety:
21227 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
21228 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
21229 // envelope_size bytes, there is always sufficient room.
21230 fidl::encoding::encode_in_envelope_optional::<
21231 fidl::encoding::Vector<
21232 fidl::encoding::Endpoint<
21233 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21234 >,
21235 64,
21236 >,
21237 fidl::encoding::DefaultFuchsiaResourceDialect,
21238 >(
21239 self.tokens.as_mut().map(
21240 <fidl::encoding::Vector<
21241 fidl::encoding::Endpoint<
21242 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21243 >,
21244 64,
21245 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
21246 ),
21247 encoder,
21248 offset + cur_offset,
21249 depth,
21250 )?;
21251
21252 _prev_end_offset = cur_offset + envelope_size;
21253
21254 Ok(())
21255 }
21256 }
21257
21258 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
21259 for BufferCollectionTokenGroupCreateChildrenSyncResponse
21260 {
21261 #[inline(always)]
21262 fn new_empty() -> Self {
21263 Self::default()
21264 }
21265
21266 unsafe fn decode(
21267 &mut self,
21268 decoder: &mut fidl::encoding::Decoder<
21269 '_,
21270 fidl::encoding::DefaultFuchsiaResourceDialect,
21271 >,
21272 offset: usize,
21273 mut depth: fidl::encoding::Depth,
21274 ) -> fidl::Result<()> {
21275 decoder.debug_check_bounds::<Self>(offset);
21276 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
21277 None => return Err(fidl::Error::NotNullable),
21278 Some(len) => len,
21279 };
21280 // Calling decoder.out_of_line_offset(0) is not allowed.
21281 if len == 0 {
21282 return Ok(());
21283 };
21284 depth.increment()?;
21285 let envelope_size = 8;
21286 let bytes_len = len * envelope_size;
21287 let offset = decoder.out_of_line_offset(bytes_len)?;
21288 // Decode the envelope for each type.
21289 let mut _next_ordinal_to_read = 0;
21290 let mut next_offset = offset;
21291 let end_offset = offset + bytes_len;
21292 _next_ordinal_to_read += 1;
21293 if next_offset >= end_offset {
21294 return Ok(());
21295 }
21296
21297 // Decode unknown envelopes for gaps in ordinals.
21298 while _next_ordinal_to_read < 1 {
21299 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21300 _next_ordinal_to_read += 1;
21301 next_offset += envelope_size;
21302 }
21303
21304 let next_out_of_line = decoder.next_out_of_line();
21305 let handles_before = decoder.remaining_handles();
21306 if let Some((inlined, num_bytes, num_handles)) =
21307 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21308 {
21309 let member_inline_size = <fidl::encoding::Vector<
21310 fidl::encoding::Endpoint<
21311 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21312 >,
21313 64,
21314 > as fidl::encoding::TypeMarker>::inline_size(
21315 decoder.context
21316 );
21317 if inlined != (member_inline_size <= 4) {
21318 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21319 }
21320 let inner_offset;
21321 let mut inner_depth = depth.clone();
21322 if inlined {
21323 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21324 inner_offset = next_offset;
21325 } else {
21326 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21327 inner_depth.increment()?;
21328 }
21329 let val_ref = self.tokens.get_or_insert_with(|| {
21330 fidl::new_empty!(
21331 fidl::encoding::Vector<
21332 fidl::encoding::Endpoint<
21333 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21334 >,
21335 64,
21336 >,
21337 fidl::encoding::DefaultFuchsiaResourceDialect
21338 )
21339 });
21340 fidl::decode!(
21341 fidl::encoding::Vector<
21342 fidl::encoding::Endpoint<
21343 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21344 >,
21345 64,
21346 >,
21347 fidl::encoding::DefaultFuchsiaResourceDialect,
21348 val_ref,
21349 decoder,
21350 inner_offset,
21351 inner_depth
21352 )?;
21353 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21354 {
21355 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21356 }
21357 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21358 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21359 }
21360 }
21361
21362 next_offset += envelope_size;
21363
21364 // Decode the remaining unknown envelopes.
21365 while next_offset < end_offset {
21366 _next_ordinal_to_read += 1;
21367 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21368 next_offset += envelope_size;
21369 }
21370
21371 Ok(())
21372 }
21373 }
21374
21375 impl BufferCollectionTokenDuplicateSyncResponse {
21376 #[inline(always)]
21377 fn max_ordinal_present(&self) -> u64 {
21378 if let Some(_) = self.tokens {
21379 return 1;
21380 }
21381 0
21382 }
21383 }
21384
21385 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateSyncResponse {
21386 type Borrowed<'a> = &'a mut Self;
21387 fn take_or_borrow<'a>(
21388 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
21389 ) -> Self::Borrowed<'a> {
21390 value
21391 }
21392 }
21393
21394 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateSyncResponse {
21395 type Owned = Self;
21396
21397 #[inline(always)]
21398 fn inline_align(_context: fidl::encoding::Context) -> usize {
21399 8
21400 }
21401
21402 #[inline(always)]
21403 fn inline_size(_context: fidl::encoding::Context) -> usize {
21404 16
21405 }
21406 }
21407
21408 unsafe impl
21409 fidl::encoding::Encode<
21410 BufferCollectionTokenDuplicateSyncResponse,
21411 fidl::encoding::DefaultFuchsiaResourceDialect,
21412 > for &mut BufferCollectionTokenDuplicateSyncResponse
21413 {
21414 unsafe fn encode(
21415 self,
21416 encoder: &mut fidl::encoding::Encoder<
21417 '_,
21418 fidl::encoding::DefaultFuchsiaResourceDialect,
21419 >,
21420 offset: usize,
21421 mut depth: fidl::encoding::Depth,
21422 ) -> fidl::Result<()> {
21423 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateSyncResponse>(offset);
21424 // Vector header
21425 let max_ordinal: u64 = self.max_ordinal_present();
21426 encoder.write_num(max_ordinal, offset);
21427 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
21428 // Calling encoder.out_of_line_offset(0) is not allowed.
21429 if max_ordinal == 0 {
21430 return Ok(());
21431 }
21432 depth.increment()?;
21433 let envelope_size = 8;
21434 let bytes_len = max_ordinal as usize * envelope_size;
21435 #[allow(unused_variables)]
21436 let offset = encoder.out_of_line_offset(bytes_len);
21437 let mut _prev_end_offset: usize = 0;
21438 if 1 > max_ordinal {
21439 return Ok(());
21440 }
21441
21442 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
21443 // are envelope_size bytes.
21444 let cur_offset: usize = (1 - 1) * envelope_size;
21445
21446 // Zero reserved fields.
21447 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
21448
21449 // Safety:
21450 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
21451 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
21452 // envelope_size bytes, there is always sufficient room.
21453 fidl::encoding::encode_in_envelope_optional::<
21454 fidl::encoding::Vector<
21455 fidl::encoding::Endpoint<
21456 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21457 >,
21458 64,
21459 >,
21460 fidl::encoding::DefaultFuchsiaResourceDialect,
21461 >(
21462 self.tokens.as_mut().map(
21463 <fidl::encoding::Vector<
21464 fidl::encoding::Endpoint<
21465 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21466 >,
21467 64,
21468 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
21469 ),
21470 encoder,
21471 offset + cur_offset,
21472 depth,
21473 )?;
21474
21475 _prev_end_offset = cur_offset + envelope_size;
21476
21477 Ok(())
21478 }
21479 }
21480
21481 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
21482 for BufferCollectionTokenDuplicateSyncResponse
21483 {
21484 #[inline(always)]
21485 fn new_empty() -> Self {
21486 Self::default()
21487 }
21488
21489 unsafe fn decode(
21490 &mut self,
21491 decoder: &mut fidl::encoding::Decoder<
21492 '_,
21493 fidl::encoding::DefaultFuchsiaResourceDialect,
21494 >,
21495 offset: usize,
21496 mut depth: fidl::encoding::Depth,
21497 ) -> fidl::Result<()> {
21498 decoder.debug_check_bounds::<Self>(offset);
21499 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
21500 None => return Err(fidl::Error::NotNullable),
21501 Some(len) => len,
21502 };
21503 // Calling decoder.out_of_line_offset(0) is not allowed.
21504 if len == 0 {
21505 return Ok(());
21506 };
21507 depth.increment()?;
21508 let envelope_size = 8;
21509 let bytes_len = len * envelope_size;
21510 let offset = decoder.out_of_line_offset(bytes_len)?;
21511 // Decode the envelope for each type.
21512 let mut _next_ordinal_to_read = 0;
21513 let mut next_offset = offset;
21514 let end_offset = offset + bytes_len;
21515 _next_ordinal_to_read += 1;
21516 if next_offset >= end_offset {
21517 return Ok(());
21518 }
21519
21520 // Decode unknown envelopes for gaps in ordinals.
21521 while _next_ordinal_to_read < 1 {
21522 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21523 _next_ordinal_to_read += 1;
21524 next_offset += envelope_size;
21525 }
21526
21527 let next_out_of_line = decoder.next_out_of_line();
21528 let handles_before = decoder.remaining_handles();
21529 if let Some((inlined, num_bytes, num_handles)) =
21530 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21531 {
21532 let member_inline_size = <fidl::encoding::Vector<
21533 fidl::encoding::Endpoint<
21534 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21535 >,
21536 64,
21537 > as fidl::encoding::TypeMarker>::inline_size(
21538 decoder.context
21539 );
21540 if inlined != (member_inline_size <= 4) {
21541 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21542 }
21543 let inner_offset;
21544 let mut inner_depth = depth.clone();
21545 if inlined {
21546 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21547 inner_offset = next_offset;
21548 } else {
21549 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21550 inner_depth.increment()?;
21551 }
21552 let val_ref = self.tokens.get_or_insert_with(|| {
21553 fidl::new_empty!(
21554 fidl::encoding::Vector<
21555 fidl::encoding::Endpoint<
21556 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21557 >,
21558 64,
21559 >,
21560 fidl::encoding::DefaultFuchsiaResourceDialect
21561 )
21562 });
21563 fidl::decode!(
21564 fidl::encoding::Vector<
21565 fidl::encoding::Endpoint<
21566 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
21567 >,
21568 64,
21569 >,
21570 fidl::encoding::DefaultFuchsiaResourceDialect,
21571 val_ref,
21572 decoder,
21573 inner_offset,
21574 inner_depth
21575 )?;
21576 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21577 {
21578 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21579 }
21580 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21581 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21582 }
21583 }
21584
21585 next_offset += envelope_size;
21586
21587 // Decode the remaining unknown envelopes.
21588 while next_offset < end_offset {
21589 _next_ordinal_to_read += 1;
21590 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21591 next_offset += envelope_size;
21592 }
21593
21594 Ok(())
21595 }
21596 }
21597
21598 impl BufferCollectionWaitForAllBuffersAllocatedResponse {
21599 #[inline(always)]
21600 fn max_ordinal_present(&self) -> u64 {
21601 if let Some(_) = self.buffer_collection_info {
21602 return 1;
21603 }
21604 0
21605 }
21606 }
21607
21608 impl fidl::encoding::ResourceTypeMarker for BufferCollectionWaitForAllBuffersAllocatedResponse {
21609 type Borrowed<'a> = &'a mut Self;
21610 fn take_or_borrow<'a>(
21611 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
21612 ) -> Self::Borrowed<'a> {
21613 value
21614 }
21615 }
21616
21617 unsafe impl fidl::encoding::TypeMarker for BufferCollectionWaitForAllBuffersAllocatedResponse {
21618 type Owned = Self;
21619
21620 #[inline(always)]
21621 fn inline_align(_context: fidl::encoding::Context) -> usize {
21622 8
21623 }
21624
21625 #[inline(always)]
21626 fn inline_size(_context: fidl::encoding::Context) -> usize {
21627 16
21628 }
21629 }
21630
21631 unsafe impl
21632 fidl::encoding::Encode<
21633 BufferCollectionWaitForAllBuffersAllocatedResponse,
21634 fidl::encoding::DefaultFuchsiaResourceDialect,
21635 > for &mut BufferCollectionWaitForAllBuffersAllocatedResponse
21636 {
21637 unsafe fn encode(
21638 self,
21639 encoder: &mut fidl::encoding::Encoder<
21640 '_,
21641 fidl::encoding::DefaultFuchsiaResourceDialect,
21642 >,
21643 offset: usize,
21644 mut depth: fidl::encoding::Depth,
21645 ) -> fidl::Result<()> {
21646 encoder
21647 .debug_check_bounds::<BufferCollectionWaitForAllBuffersAllocatedResponse>(offset);
21648 // Vector header
21649 let max_ordinal: u64 = self.max_ordinal_present();
21650 encoder.write_num(max_ordinal, offset);
21651 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
21652 // Calling encoder.out_of_line_offset(0) is not allowed.
21653 if max_ordinal == 0 {
21654 return Ok(());
21655 }
21656 depth.increment()?;
21657 let envelope_size = 8;
21658 let bytes_len = max_ordinal as usize * envelope_size;
21659 #[allow(unused_variables)]
21660 let offset = encoder.out_of_line_offset(bytes_len);
21661 let mut _prev_end_offset: usize = 0;
21662 if 1 > max_ordinal {
21663 return Ok(());
21664 }
21665
21666 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
21667 // are envelope_size bytes.
21668 let cur_offset: usize = (1 - 1) * envelope_size;
21669
21670 // Zero reserved fields.
21671 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
21672
21673 // Safety:
21674 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
21675 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
21676 // envelope_size bytes, there is always sufficient room.
21677 fidl::encoding::encode_in_envelope_optional::<
21678 BufferCollectionInfo,
21679 fidl::encoding::DefaultFuchsiaResourceDialect,
21680 >(
21681 self.buffer_collection_info.as_mut().map(
21682 <BufferCollectionInfo as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
21683 ),
21684 encoder,
21685 offset + cur_offset,
21686 depth,
21687 )?;
21688
21689 _prev_end_offset = cur_offset + envelope_size;
21690
21691 Ok(())
21692 }
21693 }
21694
21695 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
21696 for BufferCollectionWaitForAllBuffersAllocatedResponse
21697 {
21698 #[inline(always)]
21699 fn new_empty() -> Self {
21700 Self::default()
21701 }
21702
21703 unsafe fn decode(
21704 &mut self,
21705 decoder: &mut fidl::encoding::Decoder<
21706 '_,
21707 fidl::encoding::DefaultFuchsiaResourceDialect,
21708 >,
21709 offset: usize,
21710 mut depth: fidl::encoding::Depth,
21711 ) -> fidl::Result<()> {
21712 decoder.debug_check_bounds::<Self>(offset);
21713 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
21714 None => return Err(fidl::Error::NotNullable),
21715 Some(len) => len,
21716 };
21717 // Calling decoder.out_of_line_offset(0) is not allowed.
21718 if len == 0 {
21719 return Ok(());
21720 };
21721 depth.increment()?;
21722 let envelope_size = 8;
21723 let bytes_len = len * envelope_size;
21724 let offset = decoder.out_of_line_offset(bytes_len)?;
21725 // Decode the envelope for each type.
21726 let mut _next_ordinal_to_read = 0;
21727 let mut next_offset = offset;
21728 let end_offset = offset + bytes_len;
21729 _next_ordinal_to_read += 1;
21730 if next_offset >= end_offset {
21731 return Ok(());
21732 }
21733
21734 // Decode unknown envelopes for gaps in ordinals.
21735 while _next_ordinal_to_read < 1 {
21736 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21737 _next_ordinal_to_read += 1;
21738 next_offset += envelope_size;
21739 }
21740
21741 let next_out_of_line = decoder.next_out_of_line();
21742 let handles_before = decoder.remaining_handles();
21743 if let Some((inlined, num_bytes, num_handles)) =
21744 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21745 {
21746 let member_inline_size =
21747 <BufferCollectionInfo as fidl::encoding::TypeMarker>::inline_size(
21748 decoder.context,
21749 );
21750 if inlined != (member_inline_size <= 4) {
21751 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21752 }
21753 let inner_offset;
21754 let mut inner_depth = depth.clone();
21755 if inlined {
21756 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21757 inner_offset = next_offset;
21758 } else {
21759 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21760 inner_depth.increment()?;
21761 }
21762 let val_ref = self.buffer_collection_info.get_or_insert_with(|| {
21763 fidl::new_empty!(
21764 BufferCollectionInfo,
21765 fidl::encoding::DefaultFuchsiaResourceDialect
21766 )
21767 });
21768 fidl::decode!(
21769 BufferCollectionInfo,
21770 fidl::encoding::DefaultFuchsiaResourceDialect,
21771 val_ref,
21772 decoder,
21773 inner_offset,
21774 inner_depth
21775 )?;
21776 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21777 {
21778 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21779 }
21780 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21781 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21782 }
21783 }
21784
21785 next_offset += envelope_size;
21786
21787 // Decode the remaining unknown envelopes.
21788 while next_offset < end_offset {
21789 _next_ordinal_to_read += 1;
21790 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21791 next_offset += envelope_size;
21792 }
21793
21794 Ok(())
21795 }
21796 }
21797
21798 impl NodeAttachNodeTrackingRequest {
21799 #[inline(always)]
21800 fn max_ordinal_present(&self) -> u64 {
21801 if let Some(_) = self.server_end {
21802 return 1;
21803 }
21804 0
21805 }
21806 }
21807
21808 impl fidl::encoding::ResourceTypeMarker for NodeAttachNodeTrackingRequest {
21809 type Borrowed<'a> = &'a mut Self;
21810 fn take_or_borrow<'a>(
21811 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
21812 ) -> Self::Borrowed<'a> {
21813 value
21814 }
21815 }
21816
21817 unsafe impl fidl::encoding::TypeMarker for NodeAttachNodeTrackingRequest {
21818 type Owned = Self;
21819
21820 #[inline(always)]
21821 fn inline_align(_context: fidl::encoding::Context) -> usize {
21822 8
21823 }
21824
21825 #[inline(always)]
21826 fn inline_size(_context: fidl::encoding::Context) -> usize {
21827 16
21828 }
21829 }
21830
21831 unsafe impl
21832 fidl::encoding::Encode<
21833 NodeAttachNodeTrackingRequest,
21834 fidl::encoding::DefaultFuchsiaResourceDialect,
21835 > for &mut NodeAttachNodeTrackingRequest
21836 {
21837 unsafe fn encode(
21838 self,
21839 encoder: &mut fidl::encoding::Encoder<
21840 '_,
21841 fidl::encoding::DefaultFuchsiaResourceDialect,
21842 >,
21843 offset: usize,
21844 mut depth: fidl::encoding::Depth,
21845 ) -> fidl::Result<()> {
21846 encoder.debug_check_bounds::<NodeAttachNodeTrackingRequest>(offset);
21847 // Vector header
21848 let max_ordinal: u64 = self.max_ordinal_present();
21849 encoder.write_num(max_ordinal, offset);
21850 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
21851 // Calling encoder.out_of_line_offset(0) is not allowed.
21852 if max_ordinal == 0 {
21853 return Ok(());
21854 }
21855 depth.increment()?;
21856 let envelope_size = 8;
21857 let bytes_len = max_ordinal as usize * envelope_size;
21858 #[allow(unused_variables)]
21859 let offset = encoder.out_of_line_offset(bytes_len);
21860 let mut _prev_end_offset: usize = 0;
21861 if 1 > max_ordinal {
21862 return Ok(());
21863 }
21864
21865 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
21866 // are envelope_size bytes.
21867 let cur_offset: usize = (1 - 1) * envelope_size;
21868
21869 // Zero reserved fields.
21870 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
21871
21872 // Safety:
21873 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
21874 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
21875 // envelope_size bytes, there is always sufficient room.
21876 fidl::encoding::encode_in_envelope_optional::<
21877 fidl::encoding::HandleType<
21878 fidl::EventPair,
21879 { fidl::ObjectType::EVENTPAIR.into_raw() },
21880 2147483648,
21881 >,
21882 fidl::encoding::DefaultFuchsiaResourceDialect,
21883 >(
21884 self.server_end.as_mut().map(
21885 <fidl::encoding::HandleType<
21886 fidl::EventPair,
21887 { fidl::ObjectType::EVENTPAIR.into_raw() },
21888 2147483648,
21889 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
21890 ),
21891 encoder,
21892 offset + cur_offset,
21893 depth,
21894 )?;
21895
21896 _prev_end_offset = cur_offset + envelope_size;
21897
21898 Ok(())
21899 }
21900 }
21901
21902 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
21903 for NodeAttachNodeTrackingRequest
21904 {
21905 #[inline(always)]
21906 fn new_empty() -> Self {
21907 Self::default()
21908 }
21909
21910 unsafe fn decode(
21911 &mut self,
21912 decoder: &mut fidl::encoding::Decoder<
21913 '_,
21914 fidl::encoding::DefaultFuchsiaResourceDialect,
21915 >,
21916 offset: usize,
21917 mut depth: fidl::encoding::Depth,
21918 ) -> fidl::Result<()> {
21919 decoder.debug_check_bounds::<Self>(offset);
21920 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
21921 None => return Err(fidl::Error::NotNullable),
21922 Some(len) => len,
21923 };
21924 // Calling decoder.out_of_line_offset(0) is not allowed.
21925 if len == 0 {
21926 return Ok(());
21927 };
21928 depth.increment()?;
21929 let envelope_size = 8;
21930 let bytes_len = len * envelope_size;
21931 let offset = decoder.out_of_line_offset(bytes_len)?;
21932 // Decode the envelope for each type.
21933 let mut _next_ordinal_to_read = 0;
21934 let mut next_offset = offset;
21935 let end_offset = offset + bytes_len;
21936 _next_ordinal_to_read += 1;
21937 if next_offset >= end_offset {
21938 return Ok(());
21939 }
21940
21941 // Decode unknown envelopes for gaps in ordinals.
21942 while _next_ordinal_to_read < 1 {
21943 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21944 _next_ordinal_to_read += 1;
21945 next_offset += envelope_size;
21946 }
21947
21948 let next_out_of_line = decoder.next_out_of_line();
21949 let handles_before = decoder.remaining_handles();
21950 if let Some((inlined, num_bytes, num_handles)) =
21951 fidl::encoding::decode_envelope_header(decoder, next_offset)?
21952 {
21953 let member_inline_size = <fidl::encoding::HandleType<
21954 fidl::EventPair,
21955 { fidl::ObjectType::EVENTPAIR.into_raw() },
21956 2147483648,
21957 > as fidl::encoding::TypeMarker>::inline_size(
21958 decoder.context
21959 );
21960 if inlined != (member_inline_size <= 4) {
21961 return Err(fidl::Error::InvalidInlineBitInEnvelope);
21962 }
21963 let inner_offset;
21964 let mut inner_depth = depth.clone();
21965 if inlined {
21966 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
21967 inner_offset = next_offset;
21968 } else {
21969 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
21970 inner_depth.increment()?;
21971 }
21972 let val_ref =
21973 self.server_end.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
21974 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
21975 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
21976 {
21977 return Err(fidl::Error::InvalidNumBytesInEnvelope);
21978 }
21979 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
21980 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
21981 }
21982 }
21983
21984 next_offset += envelope_size;
21985
21986 // Decode the remaining unknown envelopes.
21987 while next_offset < end_offset {
21988 _next_ordinal_to_read += 1;
21989 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
21990 next_offset += envelope_size;
21991 }
21992
21993 Ok(())
21994 }
21995 }
21996
21997 impl NodeIsAlternateForRequest {
21998 #[inline(always)]
21999 fn max_ordinal_present(&self) -> u64 {
22000 if let Some(_) = self.node_ref {
22001 return 1;
22002 }
22003 0
22004 }
22005 }
22006
22007 impl fidl::encoding::ResourceTypeMarker for NodeIsAlternateForRequest {
22008 type Borrowed<'a> = &'a mut Self;
22009 fn take_or_borrow<'a>(
22010 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
22011 ) -> Self::Borrowed<'a> {
22012 value
22013 }
22014 }
22015
22016 unsafe impl fidl::encoding::TypeMarker for NodeIsAlternateForRequest {
22017 type Owned = Self;
22018
22019 #[inline(always)]
22020 fn inline_align(_context: fidl::encoding::Context) -> usize {
22021 8
22022 }
22023
22024 #[inline(always)]
22025 fn inline_size(_context: fidl::encoding::Context) -> usize {
22026 16
22027 }
22028 }
22029
22030 unsafe impl
22031 fidl::encoding::Encode<
22032 NodeIsAlternateForRequest,
22033 fidl::encoding::DefaultFuchsiaResourceDialect,
22034 > for &mut NodeIsAlternateForRequest
22035 {
22036 unsafe fn encode(
22037 self,
22038 encoder: &mut fidl::encoding::Encoder<
22039 '_,
22040 fidl::encoding::DefaultFuchsiaResourceDialect,
22041 >,
22042 offset: usize,
22043 mut depth: fidl::encoding::Depth,
22044 ) -> fidl::Result<()> {
22045 encoder.debug_check_bounds::<NodeIsAlternateForRequest>(offset);
22046 // Vector header
22047 let max_ordinal: u64 = self.max_ordinal_present();
22048 encoder.write_num(max_ordinal, offset);
22049 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
22050 // Calling encoder.out_of_line_offset(0) is not allowed.
22051 if max_ordinal == 0 {
22052 return Ok(());
22053 }
22054 depth.increment()?;
22055 let envelope_size = 8;
22056 let bytes_len = max_ordinal as usize * envelope_size;
22057 #[allow(unused_variables)]
22058 let offset = encoder.out_of_line_offset(bytes_len);
22059 let mut _prev_end_offset: usize = 0;
22060 if 1 > max_ordinal {
22061 return Ok(());
22062 }
22063
22064 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22065 // are envelope_size bytes.
22066 let cur_offset: usize = (1 - 1) * envelope_size;
22067
22068 // Zero reserved fields.
22069 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22070
22071 // Safety:
22072 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22073 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22074 // envelope_size bytes, there is always sufficient room.
22075 fidl::encoding::encode_in_envelope_optional::<
22076 fidl::encoding::HandleType<
22077 fidl::Event,
22078 { fidl::ObjectType::EVENT.into_raw() },
22079 2147483648,
22080 >,
22081 fidl::encoding::DefaultFuchsiaResourceDialect,
22082 >(
22083 self.node_ref.as_mut().map(
22084 <fidl::encoding::HandleType<
22085 fidl::Event,
22086 { fidl::ObjectType::EVENT.into_raw() },
22087 2147483648,
22088 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
22089 ),
22090 encoder,
22091 offset + cur_offset,
22092 depth,
22093 )?;
22094
22095 _prev_end_offset = cur_offset + envelope_size;
22096
22097 Ok(())
22098 }
22099 }
22100
22101 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
22102 for NodeIsAlternateForRequest
22103 {
22104 #[inline(always)]
22105 fn new_empty() -> Self {
22106 Self::default()
22107 }
22108
22109 unsafe fn decode(
22110 &mut self,
22111 decoder: &mut fidl::encoding::Decoder<
22112 '_,
22113 fidl::encoding::DefaultFuchsiaResourceDialect,
22114 >,
22115 offset: usize,
22116 mut depth: fidl::encoding::Depth,
22117 ) -> fidl::Result<()> {
22118 decoder.debug_check_bounds::<Self>(offset);
22119 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
22120 None => return Err(fidl::Error::NotNullable),
22121 Some(len) => len,
22122 };
22123 // Calling decoder.out_of_line_offset(0) is not allowed.
22124 if len == 0 {
22125 return Ok(());
22126 };
22127 depth.increment()?;
22128 let envelope_size = 8;
22129 let bytes_len = len * envelope_size;
22130 let offset = decoder.out_of_line_offset(bytes_len)?;
22131 // Decode the envelope for each type.
22132 let mut _next_ordinal_to_read = 0;
22133 let mut next_offset = offset;
22134 let end_offset = offset + bytes_len;
22135 _next_ordinal_to_read += 1;
22136 if next_offset >= end_offset {
22137 return Ok(());
22138 }
22139
22140 // Decode unknown envelopes for gaps in ordinals.
22141 while _next_ordinal_to_read < 1 {
22142 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22143 _next_ordinal_to_read += 1;
22144 next_offset += envelope_size;
22145 }
22146
22147 let next_out_of_line = decoder.next_out_of_line();
22148 let handles_before = decoder.remaining_handles();
22149 if let Some((inlined, num_bytes, num_handles)) =
22150 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22151 {
22152 let member_inline_size = <fidl::encoding::HandleType<
22153 fidl::Event,
22154 { fidl::ObjectType::EVENT.into_raw() },
22155 2147483648,
22156 > as fidl::encoding::TypeMarker>::inline_size(
22157 decoder.context
22158 );
22159 if inlined != (member_inline_size <= 4) {
22160 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22161 }
22162 let inner_offset;
22163 let mut inner_depth = depth.clone();
22164 if inlined {
22165 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22166 inner_offset = next_offset;
22167 } else {
22168 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22169 inner_depth.increment()?;
22170 }
22171 let val_ref =
22172 self.node_ref.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
22173 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
22174 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22175 {
22176 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22177 }
22178 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22179 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22180 }
22181 }
22182
22183 next_offset += envelope_size;
22184
22185 // Decode the remaining unknown envelopes.
22186 while next_offset < end_offset {
22187 _next_ordinal_to_read += 1;
22188 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22189 next_offset += envelope_size;
22190 }
22191
22192 Ok(())
22193 }
22194 }
22195
22196 impl NodeSetWeakOkRequest {
22197 #[inline(always)]
22198 fn max_ordinal_present(&self) -> u64 {
22199 if let Some(_) = self.for_child_nodes_also {
22200 return 1;
22201 }
22202 0
22203 }
22204 }
22205
22206 impl fidl::encoding::ResourceTypeMarker for NodeSetWeakOkRequest {
22207 type Borrowed<'a> = &'a mut Self;
22208 fn take_or_borrow<'a>(
22209 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
22210 ) -> Self::Borrowed<'a> {
22211 value
22212 }
22213 }
22214
22215 unsafe impl fidl::encoding::TypeMarker for NodeSetWeakOkRequest {
22216 type Owned = Self;
22217
22218 #[inline(always)]
22219 fn inline_align(_context: fidl::encoding::Context) -> usize {
22220 8
22221 }
22222
22223 #[inline(always)]
22224 fn inline_size(_context: fidl::encoding::Context) -> usize {
22225 16
22226 }
22227 }
22228
22229 unsafe impl
22230 fidl::encoding::Encode<NodeSetWeakOkRequest, fidl::encoding::DefaultFuchsiaResourceDialect>
22231 for &mut NodeSetWeakOkRequest
22232 {
22233 unsafe fn encode(
22234 self,
22235 encoder: &mut fidl::encoding::Encoder<
22236 '_,
22237 fidl::encoding::DefaultFuchsiaResourceDialect,
22238 >,
22239 offset: usize,
22240 mut depth: fidl::encoding::Depth,
22241 ) -> fidl::Result<()> {
22242 encoder.debug_check_bounds::<NodeSetWeakOkRequest>(offset);
22243 // Vector header
22244 let max_ordinal: u64 = self.max_ordinal_present();
22245 encoder.write_num(max_ordinal, offset);
22246 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
22247 // Calling encoder.out_of_line_offset(0) is not allowed.
22248 if max_ordinal == 0 {
22249 return Ok(());
22250 }
22251 depth.increment()?;
22252 let envelope_size = 8;
22253 let bytes_len = max_ordinal as usize * envelope_size;
22254 #[allow(unused_variables)]
22255 let offset = encoder.out_of_line_offset(bytes_len);
22256 let mut _prev_end_offset: usize = 0;
22257 if 1 > max_ordinal {
22258 return Ok(());
22259 }
22260
22261 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22262 // are envelope_size bytes.
22263 let cur_offset: usize = (1 - 1) * envelope_size;
22264
22265 // Zero reserved fields.
22266 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22267
22268 // Safety:
22269 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22270 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22271 // envelope_size bytes, there is always sufficient room.
22272 fidl::encoding::encode_in_envelope_optional::<
22273 bool,
22274 fidl::encoding::DefaultFuchsiaResourceDialect,
22275 >(
22276 self.for_child_nodes_also
22277 .as_ref()
22278 .map(<bool as fidl::encoding::ValueTypeMarker>::borrow),
22279 encoder,
22280 offset + cur_offset,
22281 depth,
22282 )?;
22283
22284 _prev_end_offset = cur_offset + envelope_size;
22285
22286 Ok(())
22287 }
22288 }
22289
22290 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
22291 for NodeSetWeakOkRequest
22292 {
22293 #[inline(always)]
22294 fn new_empty() -> Self {
22295 Self::default()
22296 }
22297
22298 unsafe fn decode(
22299 &mut self,
22300 decoder: &mut fidl::encoding::Decoder<
22301 '_,
22302 fidl::encoding::DefaultFuchsiaResourceDialect,
22303 >,
22304 offset: usize,
22305 mut depth: fidl::encoding::Depth,
22306 ) -> fidl::Result<()> {
22307 decoder.debug_check_bounds::<Self>(offset);
22308 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
22309 None => return Err(fidl::Error::NotNullable),
22310 Some(len) => len,
22311 };
22312 // Calling decoder.out_of_line_offset(0) is not allowed.
22313 if len == 0 {
22314 return Ok(());
22315 };
22316 depth.increment()?;
22317 let envelope_size = 8;
22318 let bytes_len = len * envelope_size;
22319 let offset = decoder.out_of_line_offset(bytes_len)?;
22320 // Decode the envelope for each type.
22321 let mut _next_ordinal_to_read = 0;
22322 let mut next_offset = offset;
22323 let end_offset = offset + bytes_len;
22324 _next_ordinal_to_read += 1;
22325 if next_offset >= end_offset {
22326 return Ok(());
22327 }
22328
22329 // Decode unknown envelopes for gaps in ordinals.
22330 while _next_ordinal_to_read < 1 {
22331 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22332 _next_ordinal_to_read += 1;
22333 next_offset += envelope_size;
22334 }
22335
22336 let next_out_of_line = decoder.next_out_of_line();
22337 let handles_before = decoder.remaining_handles();
22338 if let Some((inlined, num_bytes, num_handles)) =
22339 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22340 {
22341 let member_inline_size =
22342 <bool as fidl::encoding::TypeMarker>::inline_size(decoder.context);
22343 if inlined != (member_inline_size <= 4) {
22344 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22345 }
22346 let inner_offset;
22347 let mut inner_depth = depth.clone();
22348 if inlined {
22349 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22350 inner_offset = next_offset;
22351 } else {
22352 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22353 inner_depth.increment()?;
22354 }
22355 let val_ref = self.for_child_nodes_also.get_or_insert_with(|| {
22356 fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect)
22357 });
22358 fidl::decode!(
22359 bool,
22360 fidl::encoding::DefaultFuchsiaResourceDialect,
22361 val_ref,
22362 decoder,
22363 inner_offset,
22364 inner_depth
22365 )?;
22366 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22367 {
22368 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22369 }
22370 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22371 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22372 }
22373 }
22374
22375 next_offset += envelope_size;
22376
22377 // Decode the remaining unknown envelopes.
22378 while next_offset < end_offset {
22379 _next_ordinal_to_read += 1;
22380 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22381 next_offset += envelope_size;
22382 }
22383
22384 Ok(())
22385 }
22386 }
22387
22388 impl NodeGetNodeRefResponse {
22389 #[inline(always)]
22390 fn max_ordinal_present(&self) -> u64 {
22391 if let Some(_) = self.node_ref {
22392 return 1;
22393 }
22394 0
22395 }
22396 }
22397
22398 impl fidl::encoding::ResourceTypeMarker for NodeGetNodeRefResponse {
22399 type Borrowed<'a> = &'a mut Self;
22400 fn take_or_borrow<'a>(
22401 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
22402 ) -> Self::Borrowed<'a> {
22403 value
22404 }
22405 }
22406
22407 unsafe impl fidl::encoding::TypeMarker for NodeGetNodeRefResponse {
22408 type Owned = Self;
22409
22410 #[inline(always)]
22411 fn inline_align(_context: fidl::encoding::Context) -> usize {
22412 8
22413 }
22414
22415 #[inline(always)]
22416 fn inline_size(_context: fidl::encoding::Context) -> usize {
22417 16
22418 }
22419 }
22420
22421 unsafe impl
22422 fidl::encoding::Encode<
22423 NodeGetNodeRefResponse,
22424 fidl::encoding::DefaultFuchsiaResourceDialect,
22425 > for &mut NodeGetNodeRefResponse
22426 {
22427 unsafe fn encode(
22428 self,
22429 encoder: &mut fidl::encoding::Encoder<
22430 '_,
22431 fidl::encoding::DefaultFuchsiaResourceDialect,
22432 >,
22433 offset: usize,
22434 mut depth: fidl::encoding::Depth,
22435 ) -> fidl::Result<()> {
22436 encoder.debug_check_bounds::<NodeGetNodeRefResponse>(offset);
22437 // Vector header
22438 let max_ordinal: u64 = self.max_ordinal_present();
22439 encoder.write_num(max_ordinal, offset);
22440 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
22441 // Calling encoder.out_of_line_offset(0) is not allowed.
22442 if max_ordinal == 0 {
22443 return Ok(());
22444 }
22445 depth.increment()?;
22446 let envelope_size = 8;
22447 let bytes_len = max_ordinal as usize * envelope_size;
22448 #[allow(unused_variables)]
22449 let offset = encoder.out_of_line_offset(bytes_len);
22450 let mut _prev_end_offset: usize = 0;
22451 if 1 > max_ordinal {
22452 return Ok(());
22453 }
22454
22455 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22456 // are envelope_size bytes.
22457 let cur_offset: usize = (1 - 1) * envelope_size;
22458
22459 // Zero reserved fields.
22460 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22461
22462 // Safety:
22463 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22464 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22465 // envelope_size bytes, there is always sufficient room.
22466 fidl::encoding::encode_in_envelope_optional::<
22467 fidl::encoding::HandleType<
22468 fidl::Event,
22469 { fidl::ObjectType::EVENT.into_raw() },
22470 2147483648,
22471 >,
22472 fidl::encoding::DefaultFuchsiaResourceDialect,
22473 >(
22474 self.node_ref.as_mut().map(
22475 <fidl::encoding::HandleType<
22476 fidl::Event,
22477 { fidl::ObjectType::EVENT.into_raw() },
22478 2147483648,
22479 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
22480 ),
22481 encoder,
22482 offset + cur_offset,
22483 depth,
22484 )?;
22485
22486 _prev_end_offset = cur_offset + envelope_size;
22487
22488 Ok(())
22489 }
22490 }
22491
22492 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
22493 for NodeGetNodeRefResponse
22494 {
22495 #[inline(always)]
22496 fn new_empty() -> Self {
22497 Self::default()
22498 }
22499
22500 unsafe fn decode(
22501 &mut self,
22502 decoder: &mut fidl::encoding::Decoder<
22503 '_,
22504 fidl::encoding::DefaultFuchsiaResourceDialect,
22505 >,
22506 offset: usize,
22507 mut depth: fidl::encoding::Depth,
22508 ) -> fidl::Result<()> {
22509 decoder.debug_check_bounds::<Self>(offset);
22510 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
22511 None => return Err(fidl::Error::NotNullable),
22512 Some(len) => len,
22513 };
22514 // Calling decoder.out_of_line_offset(0) is not allowed.
22515 if len == 0 {
22516 return Ok(());
22517 };
22518 depth.increment()?;
22519 let envelope_size = 8;
22520 let bytes_len = len * envelope_size;
22521 let offset = decoder.out_of_line_offset(bytes_len)?;
22522 // Decode the envelope for each type.
22523 let mut _next_ordinal_to_read = 0;
22524 let mut next_offset = offset;
22525 let end_offset = offset + bytes_len;
22526 _next_ordinal_to_read += 1;
22527 if next_offset >= end_offset {
22528 return Ok(());
22529 }
22530
22531 // Decode unknown envelopes for gaps in ordinals.
22532 while _next_ordinal_to_read < 1 {
22533 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22534 _next_ordinal_to_read += 1;
22535 next_offset += envelope_size;
22536 }
22537
22538 let next_out_of_line = decoder.next_out_of_line();
22539 let handles_before = decoder.remaining_handles();
22540 if let Some((inlined, num_bytes, num_handles)) =
22541 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22542 {
22543 let member_inline_size = <fidl::encoding::HandleType<
22544 fidl::Event,
22545 { fidl::ObjectType::EVENT.into_raw() },
22546 2147483648,
22547 > as fidl::encoding::TypeMarker>::inline_size(
22548 decoder.context
22549 );
22550 if inlined != (member_inline_size <= 4) {
22551 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22552 }
22553 let inner_offset;
22554 let mut inner_depth = depth.clone();
22555 if inlined {
22556 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22557 inner_offset = next_offset;
22558 } else {
22559 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22560 inner_depth.increment()?;
22561 }
22562 let val_ref =
22563 self.node_ref.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
22564 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
22565 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22566 {
22567 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22568 }
22569 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22570 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22571 }
22572 }
22573
22574 next_offset += envelope_size;
22575
22576 // Decode the remaining unknown envelopes.
22577 while next_offset < end_offset {
22578 _next_ordinal_to_read += 1;
22579 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22580 next_offset += envelope_size;
22581 }
22582
22583 Ok(())
22584 }
22585 }
22586
22587 impl VmoBuffer {
22588 #[inline(always)]
22589 fn max_ordinal_present(&self) -> u64 {
22590 if let Some(_) = self.close_weak_asap {
22591 return 3;
22592 }
22593 if let Some(_) = self.vmo_usable_start {
22594 return 2;
22595 }
22596 if let Some(_) = self.vmo {
22597 return 1;
22598 }
22599 0
22600 }
22601 }
22602
22603 impl fidl::encoding::ResourceTypeMarker for VmoBuffer {
22604 type Borrowed<'a> = &'a mut Self;
22605 fn take_or_borrow<'a>(
22606 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
22607 ) -> Self::Borrowed<'a> {
22608 value
22609 }
22610 }
22611
22612 unsafe impl fidl::encoding::TypeMarker for VmoBuffer {
22613 type Owned = Self;
22614
22615 #[inline(always)]
22616 fn inline_align(_context: fidl::encoding::Context) -> usize {
22617 8
22618 }
22619
22620 #[inline(always)]
22621 fn inline_size(_context: fidl::encoding::Context) -> usize {
22622 16
22623 }
22624 }
22625
22626 unsafe impl fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>
22627 for &mut VmoBuffer
22628 {
22629 unsafe fn encode(
22630 self,
22631 encoder: &mut fidl::encoding::Encoder<
22632 '_,
22633 fidl::encoding::DefaultFuchsiaResourceDialect,
22634 >,
22635 offset: usize,
22636 mut depth: fidl::encoding::Depth,
22637 ) -> fidl::Result<()> {
22638 encoder.debug_check_bounds::<VmoBuffer>(offset);
22639 // Vector header
22640 let max_ordinal: u64 = self.max_ordinal_present();
22641 encoder.write_num(max_ordinal, offset);
22642 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
22643 // Calling encoder.out_of_line_offset(0) is not allowed.
22644 if max_ordinal == 0 {
22645 return Ok(());
22646 }
22647 depth.increment()?;
22648 let envelope_size = 8;
22649 let bytes_len = max_ordinal as usize * envelope_size;
22650 #[allow(unused_variables)]
22651 let offset = encoder.out_of_line_offset(bytes_len);
22652 let mut _prev_end_offset: usize = 0;
22653 if 1 > max_ordinal {
22654 return Ok(());
22655 }
22656
22657 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22658 // are envelope_size bytes.
22659 let cur_offset: usize = (1 - 1) * envelope_size;
22660
22661 // Zero reserved fields.
22662 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22663
22664 // Safety:
22665 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22666 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22667 // envelope_size bytes, there is always sufficient room.
22668 fidl::encoding::encode_in_envelope_optional::<
22669 fidl::encoding::HandleType<
22670 fidl::Vmo,
22671 { fidl::ObjectType::VMO.into_raw() },
22672 2147483648,
22673 >,
22674 fidl::encoding::DefaultFuchsiaResourceDialect,
22675 >(
22676 self.vmo.as_mut().map(
22677 <fidl::encoding::HandleType<
22678 fidl::Vmo,
22679 { fidl::ObjectType::VMO.into_raw() },
22680 2147483648,
22681 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
22682 ),
22683 encoder,
22684 offset + cur_offset,
22685 depth,
22686 )?;
22687
22688 _prev_end_offset = cur_offset + envelope_size;
22689 if 2 > 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 = (2 - 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 u64,
22706 fidl::encoding::DefaultFuchsiaResourceDialect,
22707 >(
22708 self.vmo_usable_start
22709 .as_ref()
22710 .map(<u64 as fidl::encoding::ValueTypeMarker>::borrow),
22711 encoder,
22712 offset + cur_offset,
22713 depth,
22714 )?;
22715
22716 _prev_end_offset = cur_offset + envelope_size;
22717 if 3 > max_ordinal {
22718 return Ok(());
22719 }
22720
22721 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
22722 // are envelope_size bytes.
22723 let cur_offset: usize = (3 - 1) * envelope_size;
22724
22725 // Zero reserved fields.
22726 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
22727
22728 // Safety:
22729 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
22730 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
22731 // envelope_size bytes, there is always sufficient room.
22732 fidl::encoding::encode_in_envelope_optional::<
22733 fidl::encoding::HandleType<
22734 fidl::EventPair,
22735 { fidl::ObjectType::EVENTPAIR.into_raw() },
22736 2147483648,
22737 >,
22738 fidl::encoding::DefaultFuchsiaResourceDialect,
22739 >(
22740 self.close_weak_asap.as_mut().map(
22741 <fidl::encoding::HandleType<
22742 fidl::EventPair,
22743 { fidl::ObjectType::EVENTPAIR.into_raw() },
22744 2147483648,
22745 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
22746 ),
22747 encoder,
22748 offset + cur_offset,
22749 depth,
22750 )?;
22751
22752 _prev_end_offset = cur_offset + envelope_size;
22753
22754 Ok(())
22755 }
22756 }
22757
22758 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect> for VmoBuffer {
22759 #[inline(always)]
22760 fn new_empty() -> Self {
22761 Self::default()
22762 }
22763
22764 unsafe fn decode(
22765 &mut self,
22766 decoder: &mut fidl::encoding::Decoder<
22767 '_,
22768 fidl::encoding::DefaultFuchsiaResourceDialect,
22769 >,
22770 offset: usize,
22771 mut depth: fidl::encoding::Depth,
22772 ) -> fidl::Result<()> {
22773 decoder.debug_check_bounds::<Self>(offset);
22774 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
22775 None => return Err(fidl::Error::NotNullable),
22776 Some(len) => len,
22777 };
22778 // Calling decoder.out_of_line_offset(0) is not allowed.
22779 if len == 0 {
22780 return Ok(());
22781 };
22782 depth.increment()?;
22783 let envelope_size = 8;
22784 let bytes_len = len * envelope_size;
22785 let offset = decoder.out_of_line_offset(bytes_len)?;
22786 // Decode the envelope for each type.
22787 let mut _next_ordinal_to_read = 0;
22788 let mut next_offset = offset;
22789 let end_offset = offset + bytes_len;
22790 _next_ordinal_to_read += 1;
22791 if next_offset >= end_offset {
22792 return Ok(());
22793 }
22794
22795 // Decode unknown envelopes for gaps in ordinals.
22796 while _next_ordinal_to_read < 1 {
22797 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22798 _next_ordinal_to_read += 1;
22799 next_offset += envelope_size;
22800 }
22801
22802 let next_out_of_line = decoder.next_out_of_line();
22803 let handles_before = decoder.remaining_handles();
22804 if let Some((inlined, num_bytes, num_handles)) =
22805 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22806 {
22807 let member_inline_size = <fidl::encoding::HandleType<
22808 fidl::Vmo,
22809 { fidl::ObjectType::VMO.into_raw() },
22810 2147483648,
22811 > as fidl::encoding::TypeMarker>::inline_size(
22812 decoder.context
22813 );
22814 if inlined != (member_inline_size <= 4) {
22815 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22816 }
22817 let inner_offset;
22818 let mut inner_depth = depth.clone();
22819 if inlined {
22820 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22821 inner_offset = next_offset;
22822 } else {
22823 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22824 inner_depth.increment()?;
22825 }
22826 let val_ref =
22827 self.vmo.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
22828 fidl::decode!(fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
22829 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22830 {
22831 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22832 }
22833 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22834 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22835 }
22836 }
22837
22838 next_offset += envelope_size;
22839 _next_ordinal_to_read += 1;
22840 if next_offset >= end_offset {
22841 return Ok(());
22842 }
22843
22844 // Decode unknown envelopes for gaps in ordinals.
22845 while _next_ordinal_to_read < 2 {
22846 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22847 _next_ordinal_to_read += 1;
22848 next_offset += envelope_size;
22849 }
22850
22851 let next_out_of_line = decoder.next_out_of_line();
22852 let handles_before = decoder.remaining_handles();
22853 if let Some((inlined, num_bytes, num_handles)) =
22854 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22855 {
22856 let member_inline_size =
22857 <u64 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
22858 if inlined != (member_inline_size <= 4) {
22859 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22860 }
22861 let inner_offset;
22862 let mut inner_depth = depth.clone();
22863 if inlined {
22864 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22865 inner_offset = next_offset;
22866 } else {
22867 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22868 inner_depth.increment()?;
22869 }
22870 let val_ref = self.vmo_usable_start.get_or_insert_with(|| {
22871 fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect)
22872 });
22873 fidl::decode!(
22874 u64,
22875 fidl::encoding::DefaultFuchsiaResourceDialect,
22876 val_ref,
22877 decoder,
22878 inner_offset,
22879 inner_depth
22880 )?;
22881 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22882 {
22883 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22884 }
22885 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22886 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22887 }
22888 }
22889
22890 next_offset += envelope_size;
22891 _next_ordinal_to_read += 1;
22892 if next_offset >= end_offset {
22893 return Ok(());
22894 }
22895
22896 // Decode unknown envelopes for gaps in ordinals.
22897 while _next_ordinal_to_read < 3 {
22898 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22899 _next_ordinal_to_read += 1;
22900 next_offset += envelope_size;
22901 }
22902
22903 let next_out_of_line = decoder.next_out_of_line();
22904 let handles_before = decoder.remaining_handles();
22905 if let Some((inlined, num_bytes, num_handles)) =
22906 fidl::encoding::decode_envelope_header(decoder, next_offset)?
22907 {
22908 let member_inline_size = <fidl::encoding::HandleType<
22909 fidl::EventPair,
22910 { fidl::ObjectType::EVENTPAIR.into_raw() },
22911 2147483648,
22912 > as fidl::encoding::TypeMarker>::inline_size(
22913 decoder.context
22914 );
22915 if inlined != (member_inline_size <= 4) {
22916 return Err(fidl::Error::InvalidInlineBitInEnvelope);
22917 }
22918 let inner_offset;
22919 let mut inner_depth = depth.clone();
22920 if inlined {
22921 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
22922 inner_offset = next_offset;
22923 } else {
22924 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
22925 inner_depth.increment()?;
22926 }
22927 let val_ref =
22928 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));
22929 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
22930 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
22931 {
22932 return Err(fidl::Error::InvalidNumBytesInEnvelope);
22933 }
22934 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
22935 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
22936 }
22937 }
22938
22939 next_offset += envelope_size;
22940
22941 // Decode the remaining unknown envelopes.
22942 while next_offset < end_offset {
22943 _next_ordinal_to_read += 1;
22944 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
22945 next_offset += envelope_size;
22946 }
22947
22948 Ok(())
22949 }
22950 }
22951}