fidl_fuchsia_sysmem/fidl_fuchsia_sysmem.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_sysmem_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
15pub struct AllocatorAllocateNonSharedCollectionRequest {
16 pub collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
17}
18
19impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
20 for AllocatorAllocateNonSharedCollectionRequest
21{
22}
23
24#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
25pub struct AllocatorAllocateSharedCollectionRequest {
26 pub token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
27}
28
29impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
30 for AllocatorAllocateSharedCollectionRequest
31{
32}
33
34#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
35pub struct AllocatorBindSharedCollectionRequest {
36 pub token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
37 pub buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
38}
39
40impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
41 for AllocatorBindSharedCollectionRequest
42{
43}
44
45#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
46pub struct AllocatorConnectToSysmem2AllocatorRequest {
47 pub allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
48}
49
50impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
51 for AllocatorConnectToSysmem2AllocatorRequest
52{
53}
54
55#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
56pub struct BufferCollectionAttachLifetimeTrackingRequest {
57 pub server_end: fidl::EventPair,
58 pub buffers_remaining: u32,
59}
60
61impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
62 for BufferCollectionAttachLifetimeTrackingRequest
63{
64}
65
66#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
67pub struct BufferCollectionAttachTokenRequest {
68 pub rights_attenuation_mask: u32,
69 pub token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
70}
71
72impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
73 for BufferCollectionAttachTokenRequest
74{
75}
76
77#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
78pub struct BufferCollectionGetAuxBuffersResponse {
79 pub status: i32,
80 pub buffer_collection_info_aux_buffers: BufferCollectionInfo2,
81}
82
83impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
84 for BufferCollectionGetAuxBuffersResponse
85{
86}
87
88/// Deprecated. Use ['fuchsia.sysmem2.BufferCollectionInfo'].
89///
90/// This type is deprecated for new code but still used by some camera code.
91#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
92pub struct BufferCollectionInfo {
93 /// The number of buffers in the collection.
94 pub buffer_count: u32,
95 /// Describes how the contents of buffers are represented.
96 /// All buffers within the collection have the same format.
97 pub format: BufferFormat,
98 /// VMO handles for each buffer in the collection.
99 /// The VMOs are only present when the buffers are backed by VMOs.
100 ///
101 /// If present, all the VMOs after `buffer_count` are invalid handles.
102 /// All buffer VMO handles have identical size and access rights.
103 /// The VMO access rights are determined based on the usages which the
104 /// client specified when allocating the buffer collection. For example,
105 /// a client which expressed a read-only usage will receive VMOs without
106 /// write rights.
107 pub vmos: [Option<fidl::Vmo>; 64],
108 /// The size of each VMO provided.
109 /// This property is only present when the buffers are backed by VMOs.
110 pub vmo_size: u64,
111}
112
113impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for BufferCollectionInfo {}
114
115/// Information about a buffer collection and its buffers.
116#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
117pub struct BufferCollectionInfo2 {
118 /// The total number of buffers.
119 pub buffer_count: u32,
120 /// These settings apply to all the buffers in the initial buffer allocation.
121 pub settings: SingleBufferSettings,
122 /// VMO handles (and vmo_usable_start offset) for each buffer in the
123 /// collection.
124 ///
125 /// If present, all the VMOs at or after index `buffer_count` are invalid
126 /// (0) handles.
127 ///
128 /// All buffer VMO handles have identical size and access rights. The size
129 /// is in settings.buffer_settings.size_bytes.
130 ///
131 /// The VMO access rights are determined based on the usages which the
132 /// client specified when allocating the buffer collection. For example,
133 /// a client which expressed a read-only usage will receive VMOs without
134 /// write rights. In addition, the rights can be attenuated by the
135 /// parameter to BufferCollectionToken.Duplicate() calls.
136 pub buffers: [VmoBuffer; 64],
137}
138
139impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for BufferCollectionInfo2 {}
140
141#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
142pub struct BufferCollectionTokenCreateBufferCollectionTokenGroupRequest {
143 pub group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
144}
145
146impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
147 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
148{
149}
150
151#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
152pub struct BufferCollectionTokenDuplicateRequest {
153 pub rights_attenuation_mask: u32,
154 pub token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
155}
156
157impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
158 for BufferCollectionTokenDuplicateRequest
159{
160}
161
162#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
163pub struct BufferCollectionTokenDuplicateSyncResponse {
164 pub tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
165}
166
167impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
168 for BufferCollectionTokenDuplicateSyncResponse
169{
170}
171
172#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
173pub struct BufferCollectionTokenGroupCreateChildrenSyncResponse {
174 pub tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
175}
176
177impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
178 for BufferCollectionTokenGroupCreateChildrenSyncResponse
179{
180}
181
182#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
183pub struct BufferCollectionWaitForBuffersAllocatedResponse {
184 pub status: i32,
185 pub buffer_collection_info: BufferCollectionInfo2,
186}
187
188impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
189 for BufferCollectionWaitForBuffersAllocatedResponse
190{
191}
192
193#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
194pub struct NodeGetNodeRefResponse {
195 pub node_ref: fidl::Event,
196}
197
198impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for NodeGetNodeRefResponse {}
199
200#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
201pub struct NodeIsAlternateForRequest {
202 pub node_ref: fidl::Event,
203}
204
205impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for NodeIsAlternateForRequest {}
206
207/// There is no current replacement for this type, but if your use case needs
208/// incremental buffer allocation within a single collection, please reach out.
209#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
210pub struct SingleBufferInfo {
211 pub settings: SingleBufferSettings,
212 pub buffer: VmoBuffer,
213}
214
215impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for SingleBufferInfo {}
216
217#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
218pub struct VmoBuffer {
219 /// The same VMO can be used by more than one CodecBuffer (only of the same
220 /// buffer_lifetime_ordinal), but each vmo handle must be a separate handle.
221 ///
222 /// The vmo field can be 0 if this is a VmoBuffer in BufferCollectionInfo_2
223 /// that's at or beyond BufferCollectionInfo_2.buffer_count.
224 pub vmo: Option<fidl::Vmo>,
225 /// Offset within the VMO of the first usable byte. Must be < the VMO's
226 /// size in bytes, and leave sufficient room for
227 /// BufferMemorySettings.size_bytes before the end of the VMO.
228 pub vmo_usable_start: u64,
229}
230
231impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for VmoBuffer {}
232
233#[derive(Debug, Default, PartialEq)]
234pub struct BufferCollectionTokenGroupCreateChildRequest {
235 /// Must be set.
236 pub token_request: Option<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
237 /// If not set, the default is ZX_RIGHT_SAME_RIGHTS.
238 pub rights_attenuation_mask: Option<u32>,
239 #[doc(hidden)]
240 pub __source_breaking: fidl::marker::SourceBreaking,
241}
242
243impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
244 for BufferCollectionTokenGroupCreateChildRequest
245{
246}
247
248#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
249pub struct AllocatorMarker;
250
251impl fidl::endpoints::ProtocolMarker for AllocatorMarker {
252 type Proxy = AllocatorProxy;
253 type RequestStream = AllocatorRequestStream;
254 #[cfg(target_os = "fuchsia")]
255 type SynchronousProxy = AllocatorSynchronousProxy;
256
257 const DEBUG_NAME: &'static str = "fuchsia.sysmem.Allocator";
258}
259impl fidl::endpoints::DiscoverableProtocolMarker for AllocatorMarker {}
260
261pub trait AllocatorProxyInterface: Send + Sync {
262 fn r#allocate_non_shared_collection(
263 &self,
264 collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
265 ) -> Result<(), fidl::Error>;
266 fn r#allocate_shared_collection(
267 &self,
268 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
269 ) -> Result<(), fidl::Error>;
270 fn r#bind_shared_collection(
271 &self,
272 token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
273 buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
274 ) -> Result<(), fidl::Error>;
275 type ValidateBufferCollectionTokenResponseFut: std::future::Future<Output = Result<bool, fidl::Error>>
276 + Send;
277 fn r#validate_buffer_collection_token(
278 &self,
279 token_server_koid: u64,
280 ) -> Self::ValidateBufferCollectionTokenResponseFut;
281 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
282 fn r#connect_to_sysmem2_allocator(
283 &self,
284 allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
285 ) -> Result<(), fidl::Error>;
286}
287#[derive(Debug)]
288#[cfg(target_os = "fuchsia")]
289pub struct AllocatorSynchronousProxy {
290 client: fidl::client::sync::Client,
291}
292
293#[cfg(target_os = "fuchsia")]
294impl fidl::endpoints::SynchronousProxy for AllocatorSynchronousProxy {
295 type Proxy = AllocatorProxy;
296 type Protocol = AllocatorMarker;
297
298 fn from_channel(inner: fidl::Channel) -> Self {
299 Self::new(inner)
300 }
301
302 fn into_channel(self) -> fidl::Channel {
303 self.client.into_channel()
304 }
305
306 fn as_channel(&self) -> &fidl::Channel {
307 self.client.as_channel()
308 }
309}
310
311#[cfg(target_os = "fuchsia")]
312impl AllocatorSynchronousProxy {
313 pub fn new(channel: fidl::Channel) -> Self {
314 let protocol_name = <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
315 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
316 }
317
318 pub fn into_channel(self) -> fidl::Channel {
319 self.client.into_channel()
320 }
321
322 /// Waits until an event arrives and returns it. It is safe for other
323 /// threads to make concurrent requests while waiting for an event.
324 pub fn wait_for_event(
325 &self,
326 deadline: zx::MonotonicInstant,
327 ) -> Result<AllocatorEvent, fidl::Error> {
328 AllocatorEvent::decode(self.client.wait_for_event(deadline)?)
329 }
330
331 /// Allocates a BufferCollection on behalf of a single client (aka initiator)
332 /// who is also the only participant (from the point of view of sysmem).
333 ///
334 /// This call exists mainly for temp/testing purposes. This call skips the
335 /// BufferCollectionToken stage, so there's no way to allow another
336 /// participant to specify its constraints.
337 ///
338 /// Real clients are encouraged to use AllocateSharedCollection() instead,
339 /// and to let relevant participants directly convey their own constraints to
340 /// sysmem.
341 ///
342 /// `collection_request` is the server end of the BufferCollection FIDL
343 /// channel. The client can call SetConstraints() and then
344 /// WaitForBuffersAllocated() on the client end of this channel to specify
345 /// constraints and then determine success/failure and get the
346 /// BufferCollectionInfo_2 for the BufferCollection. The client should also
347 /// keep the client end of this channel open while using the
348 /// BufferCollection, and should notice when this channel closes and stop
349 /// using the BufferCollection ASAP.
350 pub fn r#allocate_non_shared_collection(
351 &self,
352 mut collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
353 ) -> Result<(), fidl::Error> {
354 self.client.send::<AllocatorAllocateNonSharedCollectionRequest>(
355 (collection_request,),
356 0x20f79299bbb4d2c6,
357 fidl::encoding::DynamicFlags::empty(),
358 )
359 }
360
361 /// Creates a logical BufferCollectionToken which can be shared among
362 /// participants (using BufferCollectionToken.Duplicate()), and then
363 /// converted into a BufferCollection using BindSharedCollection().
364 ///
365 /// Success/failure to populate the BufferCollection with buffers is
366 /// determined via the BufferCollection interface.
367 pub fn r#allocate_shared_collection(
368 &self,
369 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
370 ) -> Result<(), fidl::Error> {
371 self.client.send::<AllocatorAllocateSharedCollectionRequest>(
372 (token_request,),
373 0x7a757a57bfda0f71,
374 fidl::encoding::DynamicFlags::empty(),
375 )
376 }
377
378 /// Convert a BufferCollectionToken into a connection to the logical
379 /// BufferCollection. The BufferCollection hasn't yet been populated with
380 /// buffers - the participant must first also send SetConstraints() via the
381 /// client end of buffer_collection.
382 ///
383 /// All BufferCollectionToken(s) duplicated from a logical
384 /// BufferCollectionToken created via AllocateSharedCollection() must be
385 /// turned in via BindSharedCollection() before the logical BufferCollection
386 /// will be populated with buffers.
387 ///
388 /// `token` the client endpoint of a channel whose server end was sent to
389 /// sysmem using AllocateSharedCollection or whose server end was sent to
390 /// sysmem using BufferCollectionToken.Duplicate(). The token is being
391 /// "exchanged" for a channel to the logical BufferCollection.
392 ///
393 /// `buffer_collection_request` the server end of a BufferCollection
394 /// channel. The sender retains the client end as usual. The
395 /// BufferCollection channel is a single participant's connection to the
396 /// logical BufferCollection. There typically will be other participants
397 /// with their own BufferCollection channel to the logical BufferCollection.
398 pub fn r#bind_shared_collection(
399 &self,
400 mut token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
401 mut buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
402 ) -> Result<(), fidl::Error> {
403 self.client.send::<AllocatorBindSharedCollectionRequest>(
404 (token, buffer_collection_request),
405 0x146eca7ec46ff4ee,
406 fidl::encoding::DynamicFlags::empty(),
407 )
408 }
409
410 /// Validate that a BufferCollectionToken is known to the sysmem server.
411 ///
412 /// This can be used in cases where BindSharedCollection() won't be called
413 /// until after BufferCollectionToken.Duplicate() +
414 /// BufferCollectionToken.Sync(), when the client code wants to know earlier
415 /// whether an incoming token is valid (so far).
416 ///
417 /// Calling BufferCollectionToken.Sync() on a token that isn't known to
418 /// sysmem risks the Sync() hanging forever.
419 ///
420 /// Given that an incoming token can become invalid at any time if any
421 /// participant drops their BufferCollectionToken(s) or BufferCollection(s),
422 /// authors of client code are encouraged to consider not calling
423 /// ValidateBufferCollectionToken() and instead dealing with async failure
424 /// of the BufferCollection.Sync() after all the
425 /// BufferCollectionToken.Duplicate() and BindSharedCollection() (before
426 /// sending any duplicate tokens to other processes).
427 ///
428 /// Regardless of the result of this call, this call has no effect on the
429 /// token with the referenced koid.
430 ///
431 /// A true result from this call doesn't guarantee that the token remains
432 /// valid for any duration afterwards.
433 ///
434 /// Client code will zx_object_get_info() on the client's token handle,
435 /// passing ZX_INFO_HANDLE_BASIC and getting back the related_koid
436 /// which then gets passed to ValidateBufferCollectionToken().
437 ///
438 /// If ValidateBufferCollectionToken() returns true, the token was known at
439 /// the time the sysmem server processed the call, but may no longer be
440 /// valid/known by the time the client code receives the response.
441 ///
442 /// If ValidateBufferCollectionToken() returns false, the token wasn't known
443 /// at the time the sysmem server processed the call, but the token may
444 /// become known by the time the client code receives the response. However
445 /// client code is not required to mitigate the possibility that the token
446 /// may become known late, since the source of the token should have synced
447 /// the token to sysmem before sending the token to the client code.
448 ///
449 /// If calling ValidateBufferCollectionToken() fails in some way, there will
450 /// be a zx_status_t from the FIDL layer.
451 ///
452 /// `token_server_koid` the koid of the server end of a channel that might
453 /// be a BufferCollectionToken channel. This can be obtained from
454 /// zx_object_get_info() ZX_INFO_HANDLE_BASIC related_koid.
455 pub fn r#validate_buffer_collection_token(
456 &self,
457 mut token_server_koid: u64,
458 ___deadline: zx::MonotonicInstant,
459 ) -> Result<bool, fidl::Error> {
460 let _response = self.client.send_query::<
461 AllocatorValidateBufferCollectionTokenRequest,
462 AllocatorValidateBufferCollectionTokenResponse,
463 >(
464 (token_server_koid,),
465 0x575b279b0236faea,
466 fidl::encoding::DynamicFlags::empty(),
467 ___deadline,
468 )?;
469 Ok(_response.is_known)
470 }
471
472 /// Set information about the current client that can be used by sysmem to
473 /// help debug leaking memory and hangs waiting for constraints. |name| can
474 /// be an arbitrary string, but the current process name (see
475 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
476 /// arbitrary id, but the current process ID (see
477 /// fsl::GetCurrentProcessKoid()) is a good default.
478 ///
479 /// This information is propagated to all BufferCollections created using
480 /// BindSharedCollection() or AllocateNonSharedCollection() from this
481 /// allocator. It does not affect BufferCollectionTokens, since they are
482 /// often passed cross-process and should have their names managed manually.
483 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
484 self.client.send::<AllocatorSetDebugClientInfoRequest>(
485 (name, id),
486 0x419f0d5b30728b26,
487 fidl::encoding::DynamicFlags::empty(),
488 )
489 }
490
491 /// This allows creating a sysmem2 `Allocator` given a sysmem(1)
492 /// `Allocator`.
493 ///
494 /// This is mainly useful in situations where library code is handed a
495 /// sysmem(1) allocator, but the library code has been updated to use
496 /// sysmem2. Typically the library will provide a way to pass in a sysmem2
497 /// `Allocator` instead, but client code isn't always in the same repo, so
498 /// this message allows the library to still accept the sysmem(1) Allocator
499 /// temporarily.
500 ///
501 /// The info set via `SetDebugClientInfo` (if any) is copied to the sysmem2
502 /// `Allocator`.
503 pub fn r#connect_to_sysmem2_allocator(
504 &self,
505 mut allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
506 ) -> Result<(), fidl::Error> {
507 self.client.send::<AllocatorConnectToSysmem2AllocatorRequest>(
508 (allocator_request,),
509 0x13db3e3abac2e24,
510 fidl::encoding::DynamicFlags::empty(),
511 )
512 }
513}
514
515#[derive(Debug, Clone)]
516pub struct AllocatorProxy {
517 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
518}
519
520impl fidl::endpoints::Proxy for AllocatorProxy {
521 type Protocol = AllocatorMarker;
522
523 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
524 Self::new(inner)
525 }
526
527 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
528 self.client.into_channel().map_err(|client| Self { client })
529 }
530
531 fn as_channel(&self) -> &::fidl::AsyncChannel {
532 self.client.as_channel()
533 }
534}
535
536impl AllocatorProxy {
537 /// Create a new Proxy for fuchsia.sysmem/Allocator.
538 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
539 let protocol_name = <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
540 Self { client: fidl::client::Client::new(channel, protocol_name) }
541 }
542
543 /// Get a Stream of events from the remote end of the protocol.
544 ///
545 /// # Panics
546 ///
547 /// Panics if the event stream was already taken.
548 pub fn take_event_stream(&self) -> AllocatorEventStream {
549 AllocatorEventStream { event_receiver: self.client.take_event_receiver() }
550 }
551
552 /// Allocates a BufferCollection on behalf of a single client (aka initiator)
553 /// who is also the only participant (from the point of view of sysmem).
554 ///
555 /// This call exists mainly for temp/testing purposes. This call skips the
556 /// BufferCollectionToken stage, so there's no way to allow another
557 /// participant to specify its constraints.
558 ///
559 /// Real clients are encouraged to use AllocateSharedCollection() instead,
560 /// and to let relevant participants directly convey their own constraints to
561 /// sysmem.
562 ///
563 /// `collection_request` is the server end of the BufferCollection FIDL
564 /// channel. The client can call SetConstraints() and then
565 /// WaitForBuffersAllocated() on the client end of this channel to specify
566 /// constraints and then determine success/failure and get the
567 /// BufferCollectionInfo_2 for the BufferCollection. The client should also
568 /// keep the client end of this channel open while using the
569 /// BufferCollection, and should notice when this channel closes and stop
570 /// using the BufferCollection ASAP.
571 pub fn r#allocate_non_shared_collection(
572 &self,
573 mut collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
574 ) -> Result<(), fidl::Error> {
575 AllocatorProxyInterface::r#allocate_non_shared_collection(self, collection_request)
576 }
577
578 /// Creates a logical BufferCollectionToken which can be shared among
579 /// participants (using BufferCollectionToken.Duplicate()), and then
580 /// converted into a BufferCollection using BindSharedCollection().
581 ///
582 /// Success/failure to populate the BufferCollection with buffers is
583 /// determined via the BufferCollection interface.
584 pub fn r#allocate_shared_collection(
585 &self,
586 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
587 ) -> Result<(), fidl::Error> {
588 AllocatorProxyInterface::r#allocate_shared_collection(self, token_request)
589 }
590
591 /// Convert a BufferCollectionToken into a connection to the logical
592 /// BufferCollection. The BufferCollection hasn't yet been populated with
593 /// buffers - the participant must first also send SetConstraints() via the
594 /// client end of buffer_collection.
595 ///
596 /// All BufferCollectionToken(s) duplicated from a logical
597 /// BufferCollectionToken created via AllocateSharedCollection() must be
598 /// turned in via BindSharedCollection() before the logical BufferCollection
599 /// will be populated with buffers.
600 ///
601 /// `token` the client endpoint of a channel whose server end was sent to
602 /// sysmem using AllocateSharedCollection or whose server end was sent to
603 /// sysmem using BufferCollectionToken.Duplicate(). The token is being
604 /// "exchanged" for a channel to the logical BufferCollection.
605 ///
606 /// `buffer_collection_request` the server end of a BufferCollection
607 /// channel. The sender retains the client end as usual. The
608 /// BufferCollection channel is a single participant's connection to the
609 /// logical BufferCollection. There typically will be other participants
610 /// with their own BufferCollection channel to the logical BufferCollection.
611 pub fn r#bind_shared_collection(
612 &self,
613 mut token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
614 mut buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
615 ) -> Result<(), fidl::Error> {
616 AllocatorProxyInterface::r#bind_shared_collection(self, token, buffer_collection_request)
617 }
618
619 /// Validate that a BufferCollectionToken is known to the sysmem server.
620 ///
621 /// This can be used in cases where BindSharedCollection() won't be called
622 /// until after BufferCollectionToken.Duplicate() +
623 /// BufferCollectionToken.Sync(), when the client code wants to know earlier
624 /// whether an incoming token is valid (so far).
625 ///
626 /// Calling BufferCollectionToken.Sync() on a token that isn't known to
627 /// sysmem risks the Sync() hanging forever.
628 ///
629 /// Given that an incoming token can become invalid at any time if any
630 /// participant drops their BufferCollectionToken(s) or BufferCollection(s),
631 /// authors of client code are encouraged to consider not calling
632 /// ValidateBufferCollectionToken() and instead dealing with async failure
633 /// of the BufferCollection.Sync() after all the
634 /// BufferCollectionToken.Duplicate() and BindSharedCollection() (before
635 /// sending any duplicate tokens to other processes).
636 ///
637 /// Regardless of the result of this call, this call has no effect on the
638 /// token with the referenced koid.
639 ///
640 /// A true result from this call doesn't guarantee that the token remains
641 /// valid for any duration afterwards.
642 ///
643 /// Client code will zx_object_get_info() on the client's token handle,
644 /// passing ZX_INFO_HANDLE_BASIC and getting back the related_koid
645 /// which then gets passed to ValidateBufferCollectionToken().
646 ///
647 /// If ValidateBufferCollectionToken() returns true, the token was known at
648 /// the time the sysmem server processed the call, but may no longer be
649 /// valid/known by the time the client code receives the response.
650 ///
651 /// If ValidateBufferCollectionToken() returns false, the token wasn't known
652 /// at the time the sysmem server processed the call, but the token may
653 /// become known by the time the client code receives the response. However
654 /// client code is not required to mitigate the possibility that the token
655 /// may become known late, since the source of the token should have synced
656 /// the token to sysmem before sending the token to the client code.
657 ///
658 /// If calling ValidateBufferCollectionToken() fails in some way, there will
659 /// be a zx_status_t from the FIDL layer.
660 ///
661 /// `token_server_koid` the koid of the server end of a channel that might
662 /// be a BufferCollectionToken channel. This can be obtained from
663 /// zx_object_get_info() ZX_INFO_HANDLE_BASIC related_koid.
664 pub fn r#validate_buffer_collection_token(
665 &self,
666 mut token_server_koid: u64,
667 ) -> fidl::client::QueryResponseFut<bool, fidl::encoding::DefaultFuchsiaResourceDialect> {
668 AllocatorProxyInterface::r#validate_buffer_collection_token(self, token_server_koid)
669 }
670
671 /// Set information about the current client that can be used by sysmem to
672 /// help debug leaking memory and hangs waiting for constraints. |name| can
673 /// be an arbitrary string, but the current process name (see
674 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
675 /// arbitrary id, but the current process ID (see
676 /// fsl::GetCurrentProcessKoid()) is a good default.
677 ///
678 /// This information is propagated to all BufferCollections created using
679 /// BindSharedCollection() or AllocateNonSharedCollection() from this
680 /// allocator. It does not affect BufferCollectionTokens, since they are
681 /// often passed cross-process and should have their names managed manually.
682 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
683 AllocatorProxyInterface::r#set_debug_client_info(self, name, id)
684 }
685
686 /// This allows creating a sysmem2 `Allocator` given a sysmem(1)
687 /// `Allocator`.
688 ///
689 /// This is mainly useful in situations where library code is handed a
690 /// sysmem(1) allocator, but the library code has been updated to use
691 /// sysmem2. Typically the library will provide a way to pass in a sysmem2
692 /// `Allocator` instead, but client code isn't always in the same repo, so
693 /// this message allows the library to still accept the sysmem(1) Allocator
694 /// temporarily.
695 ///
696 /// The info set via `SetDebugClientInfo` (if any) is copied to the sysmem2
697 /// `Allocator`.
698 pub fn r#connect_to_sysmem2_allocator(
699 &self,
700 mut allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
701 ) -> Result<(), fidl::Error> {
702 AllocatorProxyInterface::r#connect_to_sysmem2_allocator(self, allocator_request)
703 }
704}
705
706impl AllocatorProxyInterface for AllocatorProxy {
707 fn r#allocate_non_shared_collection(
708 &self,
709 mut collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
710 ) -> Result<(), fidl::Error> {
711 self.client.send::<AllocatorAllocateNonSharedCollectionRequest>(
712 (collection_request,),
713 0x20f79299bbb4d2c6,
714 fidl::encoding::DynamicFlags::empty(),
715 )
716 }
717
718 fn r#allocate_shared_collection(
719 &self,
720 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
721 ) -> Result<(), fidl::Error> {
722 self.client.send::<AllocatorAllocateSharedCollectionRequest>(
723 (token_request,),
724 0x7a757a57bfda0f71,
725 fidl::encoding::DynamicFlags::empty(),
726 )
727 }
728
729 fn r#bind_shared_collection(
730 &self,
731 mut token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
732 mut buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
733 ) -> Result<(), fidl::Error> {
734 self.client.send::<AllocatorBindSharedCollectionRequest>(
735 (token, buffer_collection_request),
736 0x146eca7ec46ff4ee,
737 fidl::encoding::DynamicFlags::empty(),
738 )
739 }
740
741 type ValidateBufferCollectionTokenResponseFut =
742 fidl::client::QueryResponseFut<bool, fidl::encoding::DefaultFuchsiaResourceDialect>;
743 fn r#validate_buffer_collection_token(
744 &self,
745 mut token_server_koid: u64,
746 ) -> Self::ValidateBufferCollectionTokenResponseFut {
747 fn _decode(
748 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
749 ) -> Result<bool, fidl::Error> {
750 let _response = fidl::client::decode_transaction_body::<
751 AllocatorValidateBufferCollectionTokenResponse,
752 fidl::encoding::DefaultFuchsiaResourceDialect,
753 0x575b279b0236faea,
754 >(_buf?)?;
755 Ok(_response.is_known)
756 }
757 self.client.send_query_and_decode::<AllocatorValidateBufferCollectionTokenRequest, bool>(
758 (token_server_koid,),
759 0x575b279b0236faea,
760 fidl::encoding::DynamicFlags::empty(),
761 _decode,
762 )
763 }
764
765 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
766 self.client.send::<AllocatorSetDebugClientInfoRequest>(
767 (name, id),
768 0x419f0d5b30728b26,
769 fidl::encoding::DynamicFlags::empty(),
770 )
771 }
772
773 fn r#connect_to_sysmem2_allocator(
774 &self,
775 mut allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
776 ) -> Result<(), fidl::Error> {
777 self.client.send::<AllocatorConnectToSysmem2AllocatorRequest>(
778 (allocator_request,),
779 0x13db3e3abac2e24,
780 fidl::encoding::DynamicFlags::empty(),
781 )
782 }
783}
784
785pub struct AllocatorEventStream {
786 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
787}
788
789impl std::marker::Unpin for AllocatorEventStream {}
790
791impl futures::stream::FusedStream for AllocatorEventStream {
792 fn is_terminated(&self) -> bool {
793 self.event_receiver.is_terminated()
794 }
795}
796
797impl futures::Stream for AllocatorEventStream {
798 type Item = Result<AllocatorEvent, fidl::Error>;
799
800 fn poll_next(
801 mut self: std::pin::Pin<&mut Self>,
802 cx: &mut std::task::Context<'_>,
803 ) -> std::task::Poll<Option<Self::Item>> {
804 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
805 &mut self.event_receiver,
806 cx
807 )?) {
808 Some(buf) => std::task::Poll::Ready(Some(AllocatorEvent::decode(buf))),
809 None => std::task::Poll::Ready(None),
810 }
811 }
812}
813
814#[derive(Debug)]
815pub enum AllocatorEvent {}
816
817impl AllocatorEvent {
818 /// Decodes a message buffer as a [`AllocatorEvent`].
819 fn decode(
820 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
821 ) -> Result<AllocatorEvent, fidl::Error> {
822 let (bytes, _handles) = buf.split_mut();
823 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
824 debug_assert_eq!(tx_header.tx_id, 0);
825 match tx_header.ordinal {
826 _ => Err(fidl::Error::UnknownOrdinal {
827 ordinal: tx_header.ordinal,
828 protocol_name: <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
829 }),
830 }
831 }
832}
833
834/// A Stream of incoming requests for fuchsia.sysmem/Allocator.
835pub struct AllocatorRequestStream {
836 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
837 is_terminated: bool,
838}
839
840impl std::marker::Unpin for AllocatorRequestStream {}
841
842impl futures::stream::FusedStream for AllocatorRequestStream {
843 fn is_terminated(&self) -> bool {
844 self.is_terminated
845 }
846}
847
848impl fidl::endpoints::RequestStream for AllocatorRequestStream {
849 type Protocol = AllocatorMarker;
850 type ControlHandle = AllocatorControlHandle;
851
852 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
853 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
854 }
855
856 fn control_handle(&self) -> Self::ControlHandle {
857 AllocatorControlHandle { inner: self.inner.clone() }
858 }
859
860 fn into_inner(
861 self,
862 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
863 {
864 (self.inner, self.is_terminated)
865 }
866
867 fn from_inner(
868 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
869 is_terminated: bool,
870 ) -> Self {
871 Self { inner, is_terminated }
872 }
873}
874
875impl futures::Stream for AllocatorRequestStream {
876 type Item = Result<AllocatorRequest, fidl::Error>;
877
878 fn poll_next(
879 mut self: std::pin::Pin<&mut Self>,
880 cx: &mut std::task::Context<'_>,
881 ) -> std::task::Poll<Option<Self::Item>> {
882 let this = &mut *self;
883 if this.inner.check_shutdown(cx) {
884 this.is_terminated = true;
885 return std::task::Poll::Ready(None);
886 }
887 if this.is_terminated {
888 panic!("polled AllocatorRequestStream after completion");
889 }
890 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
891 |bytes, handles| {
892 match this.inner.channel().read_etc(cx, bytes, handles) {
893 std::task::Poll::Ready(Ok(())) => {}
894 std::task::Poll::Pending => return std::task::Poll::Pending,
895 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
896 this.is_terminated = true;
897 return std::task::Poll::Ready(None);
898 }
899 std::task::Poll::Ready(Err(e)) => {
900 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
901 e.into(),
902 ))))
903 }
904 }
905
906 // A message has been received from the channel
907 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
908
909 std::task::Poll::Ready(Some(match header.ordinal {
910 0x20f79299bbb4d2c6 => {
911 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
912 let mut req = fidl::new_empty!(
913 AllocatorAllocateNonSharedCollectionRequest,
914 fidl::encoding::DefaultFuchsiaResourceDialect
915 );
916 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorAllocateNonSharedCollectionRequest>(&header, _body_bytes, handles, &mut req)?;
917 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
918 Ok(AllocatorRequest::AllocateNonSharedCollection {
919 collection_request: req.collection_request,
920
921 control_handle,
922 })
923 }
924 0x7a757a57bfda0f71 => {
925 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
926 let mut req = fidl::new_empty!(
927 AllocatorAllocateSharedCollectionRequest,
928 fidl::encoding::DefaultFuchsiaResourceDialect
929 );
930 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorAllocateSharedCollectionRequest>(&header, _body_bytes, handles, &mut req)?;
931 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
932 Ok(AllocatorRequest::AllocateSharedCollection {
933 token_request: req.token_request,
934
935 control_handle,
936 })
937 }
938 0x146eca7ec46ff4ee => {
939 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
940 let mut req = fidl::new_empty!(
941 AllocatorBindSharedCollectionRequest,
942 fidl::encoding::DefaultFuchsiaResourceDialect
943 );
944 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorBindSharedCollectionRequest>(&header, _body_bytes, handles, &mut req)?;
945 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
946 Ok(AllocatorRequest::BindSharedCollection {
947 token: req.token,
948 buffer_collection_request: req.buffer_collection_request,
949
950 control_handle,
951 })
952 }
953 0x575b279b0236faea => {
954 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
955 let mut req = fidl::new_empty!(
956 AllocatorValidateBufferCollectionTokenRequest,
957 fidl::encoding::DefaultFuchsiaResourceDialect
958 );
959 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorValidateBufferCollectionTokenRequest>(&header, _body_bytes, handles, &mut req)?;
960 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
961 Ok(AllocatorRequest::ValidateBufferCollectionToken {
962 token_server_koid: req.token_server_koid,
963
964 responder: AllocatorValidateBufferCollectionTokenResponder {
965 control_handle: std::mem::ManuallyDrop::new(control_handle),
966 tx_id: header.tx_id,
967 },
968 })
969 }
970 0x419f0d5b30728b26 => {
971 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
972 let mut req = fidl::new_empty!(
973 AllocatorSetDebugClientInfoRequest,
974 fidl::encoding::DefaultFuchsiaResourceDialect
975 );
976 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
977 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
978 Ok(AllocatorRequest::SetDebugClientInfo {
979 name: req.name,
980 id: req.id,
981
982 control_handle,
983 })
984 }
985 0x13db3e3abac2e24 => {
986 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
987 let mut req = fidl::new_empty!(
988 AllocatorConnectToSysmem2AllocatorRequest,
989 fidl::encoding::DefaultFuchsiaResourceDialect
990 );
991 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorConnectToSysmem2AllocatorRequest>(&header, _body_bytes, handles, &mut req)?;
992 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
993 Ok(AllocatorRequest::ConnectToSysmem2Allocator {
994 allocator_request: req.allocator_request,
995
996 control_handle,
997 })
998 }
999 _ => Err(fidl::Error::UnknownOrdinal {
1000 ordinal: header.ordinal,
1001 protocol_name:
1002 <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1003 }),
1004 }))
1005 },
1006 )
1007 }
1008}
1009
1010/// Allocates system memory buffers.
1011#[derive(Debug)]
1012pub enum AllocatorRequest {
1013 /// Allocates a BufferCollection on behalf of a single client (aka initiator)
1014 /// who is also the only participant (from the point of view of sysmem).
1015 ///
1016 /// This call exists mainly for temp/testing purposes. This call skips the
1017 /// BufferCollectionToken stage, so there's no way to allow another
1018 /// participant to specify its constraints.
1019 ///
1020 /// Real clients are encouraged to use AllocateSharedCollection() instead,
1021 /// and to let relevant participants directly convey their own constraints to
1022 /// sysmem.
1023 ///
1024 /// `collection_request` is the server end of the BufferCollection FIDL
1025 /// channel. The client can call SetConstraints() and then
1026 /// WaitForBuffersAllocated() on the client end of this channel to specify
1027 /// constraints and then determine success/failure and get the
1028 /// BufferCollectionInfo_2 for the BufferCollection. The client should also
1029 /// keep the client end of this channel open while using the
1030 /// BufferCollection, and should notice when this channel closes and stop
1031 /// using the BufferCollection ASAP.
1032 AllocateNonSharedCollection {
1033 collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
1034 control_handle: AllocatorControlHandle,
1035 },
1036 /// Creates a logical BufferCollectionToken which can be shared among
1037 /// participants (using BufferCollectionToken.Duplicate()), and then
1038 /// converted into a BufferCollection using BindSharedCollection().
1039 ///
1040 /// Success/failure to populate the BufferCollection with buffers is
1041 /// determined via the BufferCollection interface.
1042 AllocateSharedCollection {
1043 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
1044 control_handle: AllocatorControlHandle,
1045 },
1046 /// Convert a BufferCollectionToken into a connection to the logical
1047 /// BufferCollection. The BufferCollection hasn't yet been populated with
1048 /// buffers - the participant must first also send SetConstraints() via the
1049 /// client end of buffer_collection.
1050 ///
1051 /// All BufferCollectionToken(s) duplicated from a logical
1052 /// BufferCollectionToken created via AllocateSharedCollection() must be
1053 /// turned in via BindSharedCollection() before the logical BufferCollection
1054 /// will be populated with buffers.
1055 ///
1056 /// `token` the client endpoint of a channel whose server end was sent to
1057 /// sysmem using AllocateSharedCollection or whose server end was sent to
1058 /// sysmem using BufferCollectionToken.Duplicate(). The token is being
1059 /// "exchanged" for a channel to the logical BufferCollection.
1060 ///
1061 /// `buffer_collection_request` the server end of a BufferCollection
1062 /// channel. The sender retains the client end as usual. The
1063 /// BufferCollection channel is a single participant's connection to the
1064 /// logical BufferCollection. There typically will be other participants
1065 /// with their own BufferCollection channel to the logical BufferCollection.
1066 BindSharedCollection {
1067 token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
1068 buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
1069 control_handle: AllocatorControlHandle,
1070 },
1071 /// Validate that a BufferCollectionToken is known to the sysmem server.
1072 ///
1073 /// This can be used in cases where BindSharedCollection() won't be called
1074 /// until after BufferCollectionToken.Duplicate() +
1075 /// BufferCollectionToken.Sync(), when the client code wants to know earlier
1076 /// whether an incoming token is valid (so far).
1077 ///
1078 /// Calling BufferCollectionToken.Sync() on a token that isn't known to
1079 /// sysmem risks the Sync() hanging forever.
1080 ///
1081 /// Given that an incoming token can become invalid at any time if any
1082 /// participant drops their BufferCollectionToken(s) or BufferCollection(s),
1083 /// authors of client code are encouraged to consider not calling
1084 /// ValidateBufferCollectionToken() and instead dealing with async failure
1085 /// of the BufferCollection.Sync() after all the
1086 /// BufferCollectionToken.Duplicate() and BindSharedCollection() (before
1087 /// sending any duplicate tokens to other processes).
1088 ///
1089 /// Regardless of the result of this call, this call has no effect on the
1090 /// token with the referenced koid.
1091 ///
1092 /// A true result from this call doesn't guarantee that the token remains
1093 /// valid for any duration afterwards.
1094 ///
1095 /// Client code will zx_object_get_info() on the client's token handle,
1096 /// passing ZX_INFO_HANDLE_BASIC and getting back the related_koid
1097 /// which then gets passed to ValidateBufferCollectionToken().
1098 ///
1099 /// If ValidateBufferCollectionToken() returns true, the token was known at
1100 /// the time the sysmem server processed the call, but may no longer be
1101 /// valid/known by the time the client code receives the response.
1102 ///
1103 /// If ValidateBufferCollectionToken() returns false, the token wasn't known
1104 /// at the time the sysmem server processed the call, but the token may
1105 /// become known by the time the client code receives the response. However
1106 /// client code is not required to mitigate the possibility that the token
1107 /// may become known late, since the source of the token should have synced
1108 /// the token to sysmem before sending the token to the client code.
1109 ///
1110 /// If calling ValidateBufferCollectionToken() fails in some way, there will
1111 /// be a zx_status_t from the FIDL layer.
1112 ///
1113 /// `token_server_koid` the koid of the server end of a channel that might
1114 /// be a BufferCollectionToken channel. This can be obtained from
1115 /// zx_object_get_info() ZX_INFO_HANDLE_BASIC related_koid.
1116 ValidateBufferCollectionToken {
1117 token_server_koid: u64,
1118 responder: AllocatorValidateBufferCollectionTokenResponder,
1119 },
1120 /// Set information about the current client that can be used by sysmem to
1121 /// help debug leaking memory and hangs waiting for constraints. |name| can
1122 /// be an arbitrary string, but the current process name (see
1123 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
1124 /// arbitrary id, but the current process ID (see
1125 /// fsl::GetCurrentProcessKoid()) is a good default.
1126 ///
1127 /// This information is propagated to all BufferCollections created using
1128 /// BindSharedCollection() or AllocateNonSharedCollection() from this
1129 /// allocator. It does not affect BufferCollectionTokens, since they are
1130 /// often passed cross-process and should have their names managed manually.
1131 SetDebugClientInfo { name: String, id: u64, control_handle: AllocatorControlHandle },
1132 /// This allows creating a sysmem2 `Allocator` given a sysmem(1)
1133 /// `Allocator`.
1134 ///
1135 /// This is mainly useful in situations where library code is handed a
1136 /// sysmem(1) allocator, but the library code has been updated to use
1137 /// sysmem2. Typically the library will provide a way to pass in a sysmem2
1138 /// `Allocator` instead, but client code isn't always in the same repo, so
1139 /// this message allows the library to still accept the sysmem(1) Allocator
1140 /// temporarily.
1141 ///
1142 /// The info set via `SetDebugClientInfo` (if any) is copied to the sysmem2
1143 /// `Allocator`.
1144 ConnectToSysmem2Allocator {
1145 allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
1146 control_handle: AllocatorControlHandle,
1147 },
1148}
1149
1150impl AllocatorRequest {
1151 #[allow(irrefutable_let_patterns)]
1152 pub fn into_allocate_non_shared_collection(
1153 self,
1154 ) -> Option<(fidl::endpoints::ServerEnd<BufferCollectionMarker>, AllocatorControlHandle)> {
1155 if let AllocatorRequest::AllocateNonSharedCollection {
1156 collection_request,
1157 control_handle,
1158 } = self
1159 {
1160 Some((collection_request, control_handle))
1161 } else {
1162 None
1163 }
1164 }
1165
1166 #[allow(irrefutable_let_patterns)]
1167 pub fn into_allocate_shared_collection(
1168 self,
1169 ) -> Option<(fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>, AllocatorControlHandle)>
1170 {
1171 if let AllocatorRequest::AllocateSharedCollection { token_request, control_handle } = self {
1172 Some((token_request, control_handle))
1173 } else {
1174 None
1175 }
1176 }
1177
1178 #[allow(irrefutable_let_patterns)]
1179 pub fn into_bind_shared_collection(
1180 self,
1181 ) -> Option<(
1182 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
1183 fidl::endpoints::ServerEnd<BufferCollectionMarker>,
1184 AllocatorControlHandle,
1185 )> {
1186 if let AllocatorRequest::BindSharedCollection {
1187 token,
1188 buffer_collection_request,
1189 control_handle,
1190 } = self
1191 {
1192 Some((token, buffer_collection_request, control_handle))
1193 } else {
1194 None
1195 }
1196 }
1197
1198 #[allow(irrefutable_let_patterns)]
1199 pub fn into_validate_buffer_collection_token(
1200 self,
1201 ) -> Option<(u64, AllocatorValidateBufferCollectionTokenResponder)> {
1202 if let AllocatorRequest::ValidateBufferCollectionToken { token_server_koid, responder } =
1203 self
1204 {
1205 Some((token_server_koid, responder))
1206 } else {
1207 None
1208 }
1209 }
1210
1211 #[allow(irrefutable_let_patterns)]
1212 pub fn into_set_debug_client_info(self) -> Option<(String, u64, AllocatorControlHandle)> {
1213 if let AllocatorRequest::SetDebugClientInfo { name, id, control_handle } = self {
1214 Some((name, id, control_handle))
1215 } else {
1216 None
1217 }
1218 }
1219
1220 #[allow(irrefutable_let_patterns)]
1221 pub fn into_connect_to_sysmem2_allocator(
1222 self,
1223 ) -> Option<(
1224 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
1225 AllocatorControlHandle,
1226 )> {
1227 if let AllocatorRequest::ConnectToSysmem2Allocator { allocator_request, control_handle } =
1228 self
1229 {
1230 Some((allocator_request, control_handle))
1231 } else {
1232 None
1233 }
1234 }
1235
1236 /// Name of the method defined in FIDL
1237 pub fn method_name(&self) -> &'static str {
1238 match *self {
1239 AllocatorRequest::AllocateNonSharedCollection { .. } => {
1240 "allocate_non_shared_collection"
1241 }
1242 AllocatorRequest::AllocateSharedCollection { .. } => "allocate_shared_collection",
1243 AllocatorRequest::BindSharedCollection { .. } => "bind_shared_collection",
1244 AllocatorRequest::ValidateBufferCollectionToken { .. } => {
1245 "validate_buffer_collection_token"
1246 }
1247 AllocatorRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
1248 AllocatorRequest::ConnectToSysmem2Allocator { .. } => "connect_to_sysmem2_allocator",
1249 }
1250 }
1251}
1252
1253#[derive(Debug, Clone)]
1254pub struct AllocatorControlHandle {
1255 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1256}
1257
1258impl fidl::endpoints::ControlHandle for AllocatorControlHandle {
1259 fn shutdown(&self) {
1260 self.inner.shutdown()
1261 }
1262 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
1263 self.inner.shutdown_with_epitaph(status)
1264 }
1265
1266 fn is_closed(&self) -> bool {
1267 self.inner.channel().is_closed()
1268 }
1269 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1270 self.inner.channel().on_closed()
1271 }
1272
1273 #[cfg(target_os = "fuchsia")]
1274 fn signal_peer(
1275 &self,
1276 clear_mask: zx::Signals,
1277 set_mask: zx::Signals,
1278 ) -> Result<(), zx_status::Status> {
1279 use fidl::Peered;
1280 self.inner.channel().signal_peer(clear_mask, set_mask)
1281 }
1282}
1283
1284impl AllocatorControlHandle {}
1285
1286#[must_use = "FIDL methods require a response to be sent"]
1287#[derive(Debug)]
1288pub struct AllocatorValidateBufferCollectionTokenResponder {
1289 control_handle: std::mem::ManuallyDrop<AllocatorControlHandle>,
1290 tx_id: u32,
1291}
1292
1293/// Set the the channel to be shutdown (see [`AllocatorControlHandle::shutdown`])
1294/// if the responder is dropped without sending a response, so that the client
1295/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1296impl std::ops::Drop for AllocatorValidateBufferCollectionTokenResponder {
1297 fn drop(&mut self) {
1298 self.control_handle.shutdown();
1299 // Safety: drops once, never accessed again
1300 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1301 }
1302}
1303
1304impl fidl::endpoints::Responder for AllocatorValidateBufferCollectionTokenResponder {
1305 type ControlHandle = AllocatorControlHandle;
1306
1307 fn control_handle(&self) -> &AllocatorControlHandle {
1308 &self.control_handle
1309 }
1310
1311 fn drop_without_shutdown(mut self) {
1312 // Safety: drops once, never accessed again due to mem::forget
1313 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1314 // Prevent Drop from running (which would shut down the channel)
1315 std::mem::forget(self);
1316 }
1317}
1318
1319impl AllocatorValidateBufferCollectionTokenResponder {
1320 /// Sends a response to the FIDL transaction.
1321 ///
1322 /// Sets the channel to shutdown if an error occurs.
1323 pub fn send(self, mut is_known: bool) -> Result<(), fidl::Error> {
1324 let _result = self.send_raw(is_known);
1325 if _result.is_err() {
1326 self.control_handle.shutdown();
1327 }
1328 self.drop_without_shutdown();
1329 _result
1330 }
1331
1332 /// Similar to "send" but does not shutdown the channel if an error occurs.
1333 pub fn send_no_shutdown_on_err(self, mut is_known: bool) -> Result<(), fidl::Error> {
1334 let _result = self.send_raw(is_known);
1335 self.drop_without_shutdown();
1336 _result
1337 }
1338
1339 fn send_raw(&self, mut is_known: bool) -> Result<(), fidl::Error> {
1340 self.control_handle.inner.send::<AllocatorValidateBufferCollectionTokenResponse>(
1341 (is_known,),
1342 self.tx_id,
1343 0x575b279b0236faea,
1344 fidl::encoding::DynamicFlags::empty(),
1345 )
1346 }
1347}
1348
1349#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1350pub struct BufferCollectionMarker;
1351
1352impl fidl::endpoints::ProtocolMarker for BufferCollectionMarker {
1353 type Proxy = BufferCollectionProxy;
1354 type RequestStream = BufferCollectionRequestStream;
1355 #[cfg(target_os = "fuchsia")]
1356 type SynchronousProxy = BufferCollectionSynchronousProxy;
1357
1358 const DEBUG_NAME: &'static str = "(anonymous) BufferCollection";
1359}
1360
1361pub trait BufferCollectionProxyInterface: Send + Sync {
1362 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
1363 fn r#sync(&self) -> Self::SyncResponseFut;
1364 fn r#close(&self) -> Result<(), fidl::Error>;
1365 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
1366 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
1367 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
1368 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
1369 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
1370 + Send;
1371 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
1372 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
1373 + Send;
1374 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
1375 fn r#set_constraints(
1376 &self,
1377 has_constraints: bool,
1378 constraints: &BufferCollectionConstraints,
1379 ) -> Result<(), fidl::Error>;
1380 type WaitForBuffersAllocatedResponseFut: std::future::Future<Output = Result<(i32, BufferCollectionInfo2), fidl::Error>>
1381 + Send;
1382 fn r#wait_for_buffers_allocated(&self) -> Self::WaitForBuffersAllocatedResponseFut;
1383 type CheckBuffersAllocatedResponseFut: std::future::Future<Output = Result<i32, fidl::Error>>
1384 + Send;
1385 fn r#check_buffers_allocated(&self) -> Self::CheckBuffersAllocatedResponseFut;
1386 fn r#set_constraints_aux_buffers(
1387 &self,
1388 constraints: &BufferCollectionConstraintsAuxBuffers,
1389 ) -> Result<(), fidl::Error>;
1390 type GetAuxBuffersResponseFut: std::future::Future<Output = Result<(i32, BufferCollectionInfo2), fidl::Error>>
1391 + Send;
1392 fn r#get_aux_buffers(&self) -> Self::GetAuxBuffersResponseFut;
1393 fn r#attach_token(
1394 &self,
1395 rights_attenuation_mask: u32,
1396 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
1397 ) -> Result<(), fidl::Error>;
1398 fn r#attach_lifetime_tracking(
1399 &self,
1400 server_end: fidl::EventPair,
1401 buffers_remaining: u32,
1402 ) -> Result<(), fidl::Error>;
1403}
1404#[derive(Debug)]
1405#[cfg(target_os = "fuchsia")]
1406pub struct BufferCollectionSynchronousProxy {
1407 client: fidl::client::sync::Client,
1408}
1409
1410#[cfg(target_os = "fuchsia")]
1411impl fidl::endpoints::SynchronousProxy for BufferCollectionSynchronousProxy {
1412 type Proxy = BufferCollectionProxy;
1413 type Protocol = BufferCollectionMarker;
1414
1415 fn from_channel(inner: fidl::Channel) -> Self {
1416 Self::new(inner)
1417 }
1418
1419 fn into_channel(self) -> fidl::Channel {
1420 self.client.into_channel()
1421 }
1422
1423 fn as_channel(&self) -> &fidl::Channel {
1424 self.client.as_channel()
1425 }
1426}
1427
1428#[cfg(target_os = "fuchsia")]
1429impl BufferCollectionSynchronousProxy {
1430 pub fn new(channel: fidl::Channel) -> Self {
1431 let protocol_name = <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
1432 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
1433 }
1434
1435 pub fn into_channel(self) -> fidl::Channel {
1436 self.client.into_channel()
1437 }
1438
1439 /// Waits until an event arrives and returns it. It is safe for other
1440 /// threads to make concurrent requests while waiting for an event.
1441 pub fn wait_for_event(
1442 &self,
1443 deadline: zx::MonotonicInstant,
1444 ) -> Result<BufferCollectionEvent, fidl::Error> {
1445 BufferCollectionEvent::decode(self.client.wait_for_event(deadline)?)
1446 }
1447
1448 /// Ensure that previous messages, including Duplicate() messages on a
1449 /// token, collection, or group, have been received server side.
1450 ///
1451 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
1452 /// valid sysmem token risks the Sync() hanging forever. See
1453 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
1454 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
1455 /// Another way is to pass the token to BindSharedCollection(), which also
1456 /// validates the token as part of exchanging it for a BufferCollection
1457 /// channel, and BufferCollection Sync() can then be used.
1458 ///
1459 /// After a Sync(), it's then safe to send the client end of token_request
1460 /// to another participant knowing the server will recognize the token when
1461 /// it's sent into BindSharedCollection() by the other participant.
1462 ///
1463 /// Other options include waiting for each token.Duplicate() to complete
1464 /// individually (using separate call to token.Sync() after each), or
1465 /// calling Sync() on BufferCollection after the token has been turned in
1466 /// via BindSharedCollection().
1467 ///
1468 /// Another way to mitigate is to avoid calling Sync() on the token, and
1469 /// instead later deal with potential failure of BufferCollection.Sync() if
1470 /// the original token was invalid. This option can be preferable from a
1471 /// performance point of view, but requires client code to delay sending
1472 /// tokens duplicated from this token until after client code has converted
1473 /// the duplicating token to a BufferCollection and received successful
1474 /// response from BufferCollection.Sync().
1475 ///
1476 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
1477 /// When BufferCollection.Sync() isn't feasible, the caller must already
1478 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
1479 /// hang forever. See ValidateBufferCollectionToken() to check token
1480 /// validity first if the token isn't already known to be (is/was) valid.
1481 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
1482 let _response =
1483 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
1484 (),
1485 0x4577e238ae26291,
1486 fidl::encoding::DynamicFlags::empty(),
1487 ___deadline,
1488 )?;
1489 Ok(_response)
1490 }
1491
1492 /// On a BufferCollectionToken channel:
1493 ///
1494 /// Normally a participant will convert a BufferCollectionToken into a
1495 /// BufferCollection view, but a participant is also free to Close() the
1496 /// token (and then close the channel immediately or shortly later in
1497 /// response to server closing its end), which avoids causing logical buffer
1498 /// collection failure. Â Normally an unexpected token channel close will
1499 /// cause logical buffer collection failure (the only exceptions being
1500 /// certain cases involving AttachToken() or SetDispensable()).
1501 ///
1502 /// On a BufferCollection channel:
1503 ///
1504 /// By default the server handles unexpected failure of a BufferCollection
1505 /// by failing the whole logical buffer collection. Partly this is to
1506 /// expedite closing VMO handles to reclaim memory when any participant
1507 /// fails. If a participant would like to cleanly close a BufferCollection
1508 /// view without causing logical buffer collection failure, the participant
1509 /// can send Close() before closing the client end of the BufferCollection
1510 /// channel. If this is the last BufferCollection view, the logical buffer
1511 /// collection will still go away. The Close() can occur before or after
1512 /// SetConstraints(). If before SetConstraints(), the buffer collection
1513 /// won't require constraints from this node in order to allocate. If
1514 /// after SetConstraints(), the constraints are retained and aggregated
1515 /// along with any subsequent logical allocation(s), despite the lack of
1516 /// channel connection.
1517 ///
1518 /// On a BufferCollectionTokenGroup channel:
1519 ///
1520 /// By default, unexpected failure of a BufferCollectionTokenGroup will
1521 /// trigger failure of the logical BufferCollectionTokenGroup and will
1522 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
1523 /// channel without failing the logical group or propagating failure, send
1524 /// Close() before closing the channel client endpoint.
1525 ///
1526 /// If Close() occurs before AllChildrenPresent(), the logical buffer
1527 /// collection will still fail despite the Close() (because sysmem can't be
1528 /// sure whether all relevant children were created, so it's ambiguous
1529 /// whether all relevant constraints will be provided to sysmem). If
1530 /// Close() occurs after AllChildrenPresent(), the children and all their
1531 /// constraints remain intact (just as they would if the
1532 /// BufferCollectionTokenGroup channel had remained open), and the close
1533 /// doesn't trigger or propagate failure.
1534 pub fn r#close(&self) -> Result<(), fidl::Error> {
1535 self.client.send::<fidl::encoding::EmptyPayload>(
1536 (),
1537 0x5b1d7a4f5681fca7,
1538 fidl::encoding::DynamicFlags::empty(),
1539 )
1540 }
1541
1542 /// Set a name for VMOs in this buffer collection. The name may be truncated
1543 /// shorter. The name only affects VMOs allocated after it's set - this call
1544 /// does not rename existing VMOs. If multiple clients set different names
1545 /// then the larger priority value will win.
1546 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
1547 self.client.send::<NodeSetNameRequest>(
1548 (priority, name),
1549 0x77a41bb6217e2443,
1550 fidl::encoding::DynamicFlags::empty(),
1551 )
1552 }
1553
1554 /// Set information about the current client that can be used by sysmem to
1555 /// help debug leaking memory and hangs waiting for constraints. |name| can
1556 /// be an arbitrary string, but the current process name (see
1557 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
1558 /// arbitrary id, but the current process ID (see
1559 /// fsl::GetCurrentProcessKoid()) is a good default.
1560 ///
1561 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
1562 /// indicate which client is closing their channel first, leading to
1563 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
1564 /// over, but if happening earlier than expected, the
1565 /// client-channel-specific name can help diagnose where the failure is
1566 /// first coming from, from sysmem's point of view).
1567 ///
1568 /// By default (unless overriden by this message or using
1569 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
1570 /// parent Node at the time the child Node is created. While this can be
1571 /// better than nothing, it's often better for each participant to use
1572 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
1573 /// info directly relevant to the current client. Also, SetVerboseLogging()
1574 /// can be used to help disambiguate if a Node is suspected of having info
1575 /// that was copied from its parent.
1576 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
1577 self.client.send::<NodeSetDebugClientInfoRequest>(
1578 (name, id),
1579 0x7275759070eb5ee2,
1580 fidl::encoding::DynamicFlags::empty(),
1581 )
1582 }
1583
1584 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
1585 /// after creating a collection. Clients can call this method to change
1586 /// when the log is printed. If multiple client set the deadline, it's
1587 /// unspecified which deadline will take effect.
1588 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
1589 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
1590 (deadline,),
1591 0x46d38f4772638867,
1592 fidl::encoding::DynamicFlags::empty(),
1593 )
1594 }
1595
1596 /// Verbose logging includes constraints set via SetConstraints() from each
1597 /// client along with info set via SetDebugClientInfo() and the structure of
1598 /// the tree of Node(s).
1599 ///
1600 /// Normally sysmem prints only a single line complaint when aggregation
1601 /// fails, with just the specific detailed reason that aggregation failed,
1602 /// with minimal context. While this is often enough to diagnose a problem
1603 /// if only a small change was made and the system had been working before
1604 /// the small change, it's often not particularly helpful for getting a new
1605 /// buffer collection to work for the first time. Especially with more
1606 /// complex trees of nodes, involving things like AttachToken(),
1607 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
1608 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
1609 /// looks like and why it's failing a logical allocation, or why a tree or
1610 /// sub-tree is failing sooner than expected.
1611 ///
1612 /// The intent of the extra logging is to be acceptable from a performance
1613 /// point of view, if only enabled on a low number of buffer collections.
1614 /// If we're not tracking down a bug, we shouldn't send this message.
1615 ///
1616 /// If too many participants leave verbose logging enabled, we may end up
1617 /// needing to require that system-wide sysmem verbose logging be permitted
1618 /// via some other setting, to avoid sysmem spamming the log too much due to
1619 /// this message.
1620 ///
1621 /// This may be a NOP for some nodes due to intentional policy associated
1622 /// with the node, if we don't trust a node enough to let it turn on verbose
1623 /// logging.
1624 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
1625 self.client.send::<fidl::encoding::EmptyPayload>(
1626 (),
1627 0x6bfbe2cf1701d288,
1628 fidl::encoding::DynamicFlags::empty(),
1629 )
1630 }
1631
1632 /// This gets an event handle that can be used as a parameter to
1633 /// IsAlternateFor() called on any Node. The client will not be granted the
1634 /// right to signal this event, as this handle should only be used as proof
1635 /// that the client obtained this handle from this Node.
1636 ///
1637 /// Because this is a get not a set, no Sync() is needed between the
1638 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
1639 /// potentially being on different channels.
1640 ///
1641 /// See also IsAlternateFor().
1642 pub fn r#get_node_ref(
1643 &self,
1644 ___deadline: zx::MonotonicInstant,
1645 ) -> Result<fidl::Event, fidl::Error> {
1646 let _response =
1647 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
1648 (),
1649 0x467b7c75c35c3b84,
1650 fidl::encoding::DynamicFlags::empty(),
1651 ___deadline,
1652 )?;
1653 Ok(_response.node_ref)
1654 }
1655
1656 /// This checks whether the calling node is in a subtree rooted at a
1657 /// different child token of a common parent BufferCollectionTokenGroup, in
1658 /// relation to the passed-in node_ref.
1659 ///
1660 /// This call is for assisting with admission control de-duplication, and
1661 /// with debugging.
1662 ///
1663 /// The node_ref must be obtained using GetNodeRef() of a
1664 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
1665 ///
1666 /// The node_ref can be a duplicated handle; it's not necessary to call
1667 /// GetNodeRef() for every call to IsAlternateFor().
1668 ///
1669 /// If a calling token may not actually be a valid token at all due to
1670 /// a potentially hostile/untrusted provider of the token, call
1671 /// ValidateBufferCollectionToken() first instead of potentially getting
1672 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
1673 /// token not being a real token (not really talking to sysmem). Another
1674 /// option is to call BindSharedCollection with this token first which also
1675 /// validates the token along with converting it to a BufferCollection, then
1676 /// call BufferCollection IsAlternateFor().
1677 ///
1678 /// error values:
1679 ///
1680 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
1681 /// buffer collection as the calling Node. Before logical allocation and
1682 /// within the same logical allocation sub-tree, this essentially means that
1683 /// the node_ref was never part of this logical buffer collection, since
1684 /// before logical allocation all node_refs that come into existence remain
1685 /// in existence at least until logical allocation (including Node(s) that
1686 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
1687 /// to be returned, this Node's channel needs to still be connected server
1688 /// side, which won't be the case if the whole logical allocation has
1689 /// failed. After logical allocation or in a different logical allocation
1690 /// sub-tree there are additional potential reasons for this error. For
1691 /// example a different logical allocation (separated from this Node(s)
1692 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
1693 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
1694 /// exist and may select a different child sub-tree than the sub-tree the
1695 /// node_ref is in causing deletion of the node_ref Node. The only time
1696 /// sysmem keeps a Node around after that Node has no corresponding channel
1697 /// is when Close() is used and the Node's sub-tree has not yet failed.
1698 /// Another reason for this error is if the node_ref is an eventpair handle
1699 /// with sufficient rights, but isn't actually a real node_ref obtained from
1700 /// GetNodeRef().
1701 ///
1702 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
1703 /// eventpair handle, or doesn't have the needed rights expected on a real
1704 /// node_ref.
1705 ///
1706 /// No other failing status codes are returned by this call. However,
1707 /// sysmem may add additional codes in future, so the client should have
1708 /// sensible default handling for any failing status code.
1709 ///
1710 /// On success, is_alternate has the following meaning:
1711 /// * true - The first parent node in common between the calling node and
1712 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
1713 /// the calling Node and the node_ref Node will _not_ have both their
1714 /// constraints apply - rather sysmem will choose one or the other of
1715 /// the constraints - never both. This is because only one child of
1716 /// a BufferCollectionTokenGroup is selected during logical allocation,
1717 /// with only that one child's sub-tree contributing to constraints
1718 /// aggregation.
1719 /// * false - The first parent node in common between the calling Node and
1720 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
1721 /// this means the first parent node in common is a
1722 /// BufferCollectionToken or BufferCollection (regardless of not
1723 /// Close()ed or Close()ed). This means that the calling Node and the
1724 /// node_ref Node _may_ have both their constraints apply during
1725 /// constraints aggregation of the logical allocation, if both Node(s)
1726 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
1727 /// In this case, there is no BufferCollectionTokenGroup that will
1728 /// directly prevent the two Node(s) from both being selected and their
1729 /// constraints both aggregated, but even when false, one or both
1730 /// Node(s) may still be eliminated from consideration if one or both
1731 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
1732 /// which selects a child sub-tree other than the sub-tree containing
1733 /// the calling Node or node_ref Node.
1734 pub fn r#is_alternate_for(
1735 &self,
1736 mut node_ref: fidl::Event,
1737 ___deadline: zx::MonotonicInstant,
1738 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
1739 let _response = self.client.send_query::<
1740 NodeIsAlternateForRequest,
1741 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
1742 >(
1743 (node_ref,),
1744 0x33a2a7aff2776c07,
1745 fidl::encoding::DynamicFlags::empty(),
1746 ___deadline,
1747 )?;
1748 Ok(_response.map(|x| x.is_alternate))
1749 }
1750
1751 /// Provide BufferCollectionConstraints to the logical BufferCollection.
1752 ///
1753 /// A participant may only call SetConstraints() once.
1754 ///
1755 /// Sometimes the initiator is a participant only in the sense of wanting to
1756 /// keep an eye on success/failure to populate with buffers, and zx.Status
1757 /// on failure. In that case, `has_constraints` can be false, and
1758 /// `constraints` will be ignored.
1759 ///
1760 /// VMO handles will not be provided to the client that sends null
1761 /// constraints - that can be intentional for an initiator that doesn't need
1762 /// VMO handles. Not having VMO handles doesn't prevent the initator from
1763 /// adjusting which portion of a buffer is considered valid and similar, but
1764 /// the initiator can't hold a VMO handle open to prevent the logical
1765 /// BufferCollection from cleaning up if the logical BufferCollection needs
1766 /// to go away regardless of the initiator's degree of involvement for
1767 /// whatever reason.
1768 ///
1769 /// For population of buffers to be attempted, all holders of a
1770 /// BufferCollection client channel need to call SetConstraints() before
1771 /// sysmem will attempt to allocate buffers.
1772 ///
1773 /// `has_constraints` if false, the constraints are effectively null, and
1774 /// `constraints` are ignored. The sender of null constraints won't get any
1775 /// VMO handles in BufferCollectionInfo, but can still find out how many
1776 /// buffers were allocated and can still refer to buffers by their
1777 /// buffer_index.
1778 ///
1779 /// `constraints` are constraints on the buffer collection.
1780 pub fn r#set_constraints(
1781 &self,
1782 mut has_constraints: bool,
1783 mut constraints: &BufferCollectionConstraints,
1784 ) -> Result<(), fidl::Error> {
1785 self.client.send::<BufferCollectionSetConstraintsRequest>(
1786 (has_constraints, constraints),
1787 0x4d9c3406c213227b,
1788 fidl::encoding::DynamicFlags::empty(),
1789 )
1790 }
1791
1792 /// This request completes when buffers have been allocated, responds with
1793 /// some failure detail if allocation has been attempted but failed.
1794 ///
1795 /// The following must occur before buffers will be allocated:
1796 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
1797 /// must be turned in via BindSharedCollection().
1798 /// * All BufferCollection(s) of the logical BufferCollection must have
1799 /// had SetConstraints() sent to them.
1800 ///
1801 /// Returns `ZX_OK` if successful.
1802 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
1803 /// fulfilled due to resource exhaustion.
1804 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
1805 /// obtain the buffers it requested.
1806 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
1807 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
1808 /// satisfied, perhaps due to hardware limitations.
1809 ///
1810 /// `buffer_collection_info` has the VMO handles and other related info.
1811 pub fn r#wait_for_buffers_allocated(
1812 &self,
1813 ___deadline: zx::MonotonicInstant,
1814 ) -> Result<(i32, BufferCollectionInfo2), fidl::Error> {
1815 let _response = self.client.send_query::<
1816 fidl::encoding::EmptyPayload,
1817 BufferCollectionWaitForBuffersAllocatedResponse,
1818 >(
1819 (),
1820 0x714667ea2a29a3a2,
1821 fidl::encoding::DynamicFlags::empty(),
1822 ___deadline,
1823 )?;
1824 Ok((_response.status, _response.buffer_collection_info))
1825 }
1826
1827 /// This returns the same result code as WaitForBuffersAllocated if the
1828 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
1829 /// if WaitForBuffersAllocated would block.
1830 pub fn r#check_buffers_allocated(
1831 &self,
1832 ___deadline: zx::MonotonicInstant,
1833 ) -> Result<i32, fidl::Error> {
1834 let _response = self.client.send_query::<
1835 fidl::encoding::EmptyPayload,
1836 BufferCollectionCheckBuffersAllocatedResponse,
1837 >(
1838 (),
1839 0x245bb81f79189e9,
1840 fidl::encoding::DynamicFlags::empty(),
1841 ___deadline,
1842 )?;
1843 Ok(_response.status)
1844 }
1845
1846 pub fn r#set_constraints_aux_buffers(
1847 &self,
1848 mut constraints: &BufferCollectionConstraintsAuxBuffers,
1849 ) -> Result<(), fidl::Error> {
1850 self.client.send::<BufferCollectionSetConstraintsAuxBuffersRequest>(
1851 (constraints,),
1852 0x1ad80e63c090d817,
1853 fidl::encoding::DynamicFlags::empty(),
1854 )
1855 }
1856
1857 pub fn r#get_aux_buffers(
1858 &self,
1859 ___deadline: zx::MonotonicInstant,
1860 ) -> Result<(i32, BufferCollectionInfo2), fidl::Error> {
1861 let _response = self
1862 .client
1863 .send_query::<fidl::encoding::EmptyPayload, BufferCollectionGetAuxBuffersResponse>(
1864 (),
1865 0x6c6cac6000a29a55,
1866 fidl::encoding::DynamicFlags::empty(),
1867 ___deadline,
1868 )?;
1869 Ok((_response.status, _response.buffer_collection_info_aux_buffers))
1870 }
1871
1872 /// Create a new token, for trying to add a new participant to an existing
1873 /// collection, if the existing collection's buffer counts, constraints,
1874 /// and participants allow.
1875 ///
1876 /// This can be useful in replacing a failed participant, and/or in
1877 /// adding/re-adding a participant after buffers have already been
1878 /// allocated.
1879 ///
1880 /// Failure of an attached token / collection does not propagate to the
1881 /// parent of the attached token. Failure does propagate from a normal
1882 /// child of a dispensable token to the dispensable token. Failure
1883 /// of a child is blocked from reaching its parent if the child is attached,
1884 /// or if the child is dispensable and the failure occurred after logical
1885 /// allocation.
1886 ///
1887 /// An initiator may in some scenarios choose to initially use a dispensable
1888 /// token for a given instance of a participant, and then later if the first
1889 /// instance of that participant fails, a new second instance of that
1890 /// participant my be given a token created with AttachToken().
1891 ///
1892 /// From the point of view of the client end of the BufferCollectionToken
1893 /// channel, the token acts like any other token. The client can
1894 /// Duplicate() the token as needed, and can send the token to a different
1895 /// process. The token should be converted to a BufferCollection channel
1896 /// as normal by calling BindSharedCollection(). SetConstraints() should
1897 /// be called on that BufferCollection channel.
1898 ///
1899 /// A success result from WaitForBuffersAllocated() means the new
1900 /// participant's constraints were satisfiable using the already-existing
1901 /// buffer collection, the already-established BufferCollectionInfo
1902 /// including image format constraints, and the already-existing other
1903 /// participants and their buffer counts. A failure result means the new
1904 /// participant's constraints cannot be satisfied using the existing
1905 /// buffer collection and its already-logically-allocated participants.
1906 /// Creating a new collection instead may allow all participant's
1907 /// constraints to be satisfied, assuming SetDispensable() is used in place
1908 /// of AttachToken(), or a normal token is used.
1909 ///
1910 /// A token created with AttachToken() performs constraints aggregation with
1911 /// all constraints currently in effect on the buffer collection, plus the
1912 /// attached token under consideration plus child tokens under the attached
1913 /// token which are not themselves an attached token or under such a token.
1914 ///
1915 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
1916 /// first-come first-served, but a child can't logically allocate before
1917 /// all its parents have sent SetConstraints().
1918 ///
1919 /// See also SetDispensable(), which in contrast to AttachToken(), has the
1920 /// created token + children participate in constraints aggregation along
1921 /// with its parent.
1922 ///
1923 /// The newly created token needs to be Sync()ed to sysmem before the new
1924 /// token can be passed to BindSharedCollection(). The Sync() of the new
1925 /// token can be accomplished with BufferCollection.Sync() on this
1926 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
1927 /// token also works. A BufferCollectionToken.Sync() can be started after
1928 /// any BufferCollectionToken.Duplicate() messages have been sent via the
1929 /// newly created token, to also sync those additional tokens to sysmem
1930 /// using a single round-trip.
1931 ///
1932 /// These values for rights_attenuation_mask result in no attenuation (note
1933 /// that 0 is not on this list; 0 will output an ERROR to the system log
1934 /// to help diagnose the bug in client code):
1935 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
1936 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
1937 pub fn r#attach_token(
1938 &self,
1939 mut rights_attenuation_mask: u32,
1940 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
1941 ) -> Result<(), fidl::Error> {
1942 self.client.send::<BufferCollectionAttachTokenRequest>(
1943 (rights_attenuation_mask, token_request),
1944 0x6f5adcca4ac7443e,
1945 fidl::encoding::DynamicFlags::empty(),
1946 )
1947 }
1948
1949 /// AttachLifetimeTracking:
1950 ///
1951 /// AttachLifetimeTracking() is intended to allow a client to wait until an
1952 /// old logical buffer collection is fully or mostly deallocated before
1953 /// attempting allocation of a new logical buffer collection.
1954 ///
1955 /// Attach an eventpair endpoint to the logical buffer collection, so that
1956 /// the server_end will be closed when the number of buffers allocated
1957 /// drops to 'buffers_remaining'. The server_end won't close until after
1958 /// logical allocation has completed.
1959 ///
1960 /// If logical allocation fails, such as for an attached sub-tree (using
1961 /// AttachToken()), the server_end will close during that failure regardless
1962 /// of the number of buffers potenitally allocated in the overall logical
1963 /// buffer collection.
1964 ///
1965 /// The lifetime signalled by this event includes asynchronous cleanup of
1966 /// allocated buffers, and this asynchronous cleanup cannot occur until all
1967 /// holders of VMO handles to the buffers have closed those VMO handles.
1968 /// Therefore clients should take care not to become blocked forever waiting
1969 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
1970 /// participants using the logical buffer collection are less trusted or
1971 /// less reliable.
1972 ///
1973 /// The buffers_remaining parameter allows waiting for all but
1974 /// buffers_remaining buffers to be fully deallocated. This can be useful
1975 /// in situations where a known number of buffers are intentionally not
1976 /// closed so that the data can continue to be used, such as for keeping the
1977 /// last available video picture displayed in the UI even if the video
1978 /// stream was using protected output buffers. It's outside the scope of
1979 /// the BufferCollection interface (at least for now) to determine how many
1980 /// buffers may be held without closing, but it'll typically be in the range
1981 /// 0-2.
1982 ///
1983 /// This mechanism is meant to be compatible with other protocols providing
1984 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
1985 /// same event can be sent to more than one AttachLifetimeTracking(), and
1986 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
1987 /// over conditions are met (all holders of duplicates have closed their
1988 /// handle(s)).
1989 ///
1990 /// There is no way to cancel an attach. Closing the client end of the
1991 /// eventpair doesn't subtract from the number of pending attach(es).
1992 ///
1993 /// Closing the client's end doesn't result in any action by the server.
1994 /// If the server listens to events from the client end at all, it is for
1995 /// debug logging only.
1996 ///
1997 /// The server intentionally doesn't "trust" any bits signalled by the
1998 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
1999 /// which can't be triggered early, and is only triggered when all handles
2000 /// to server_end are closed. No meaning is associated with any of the
2001 /// other signal bits, and clients should functionally ignore any other
2002 /// signal bits on either end of the eventpair or its peer.
2003 ///
2004 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
2005 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
2006 /// transfer without causing CodecFactory channel failure).
2007 pub fn r#attach_lifetime_tracking(
2008 &self,
2009 mut server_end: fidl::EventPair,
2010 mut buffers_remaining: u32,
2011 ) -> Result<(), fidl::Error> {
2012 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
2013 (server_end, buffers_remaining),
2014 0x170d0f1d89d50989,
2015 fidl::encoding::DynamicFlags::empty(),
2016 )
2017 }
2018}
2019
2020#[derive(Debug, Clone)]
2021pub struct BufferCollectionProxy {
2022 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
2023}
2024
2025impl fidl::endpoints::Proxy for BufferCollectionProxy {
2026 type Protocol = BufferCollectionMarker;
2027
2028 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
2029 Self::new(inner)
2030 }
2031
2032 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
2033 self.client.into_channel().map_err(|client| Self { client })
2034 }
2035
2036 fn as_channel(&self) -> &::fidl::AsyncChannel {
2037 self.client.as_channel()
2038 }
2039}
2040
2041impl BufferCollectionProxy {
2042 /// Create a new Proxy for fuchsia.sysmem/BufferCollection.
2043 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
2044 let protocol_name = <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
2045 Self { client: fidl::client::Client::new(channel, protocol_name) }
2046 }
2047
2048 /// Get a Stream of events from the remote end of the protocol.
2049 ///
2050 /// # Panics
2051 ///
2052 /// Panics if the event stream was already taken.
2053 pub fn take_event_stream(&self) -> BufferCollectionEventStream {
2054 BufferCollectionEventStream { event_receiver: self.client.take_event_receiver() }
2055 }
2056
2057 /// Ensure that previous messages, including Duplicate() messages on a
2058 /// token, collection, or group, have been received server side.
2059 ///
2060 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
2061 /// valid sysmem token risks the Sync() hanging forever. See
2062 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
2063 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
2064 /// Another way is to pass the token to BindSharedCollection(), which also
2065 /// validates the token as part of exchanging it for a BufferCollection
2066 /// channel, and BufferCollection Sync() can then be used.
2067 ///
2068 /// After a Sync(), it's then safe to send the client end of token_request
2069 /// to another participant knowing the server will recognize the token when
2070 /// it's sent into BindSharedCollection() by the other participant.
2071 ///
2072 /// Other options include waiting for each token.Duplicate() to complete
2073 /// individually (using separate call to token.Sync() after each), or
2074 /// calling Sync() on BufferCollection after the token has been turned in
2075 /// via BindSharedCollection().
2076 ///
2077 /// Another way to mitigate is to avoid calling Sync() on the token, and
2078 /// instead later deal with potential failure of BufferCollection.Sync() if
2079 /// the original token was invalid. This option can be preferable from a
2080 /// performance point of view, but requires client code to delay sending
2081 /// tokens duplicated from this token until after client code has converted
2082 /// the duplicating token to a BufferCollection and received successful
2083 /// response from BufferCollection.Sync().
2084 ///
2085 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
2086 /// When BufferCollection.Sync() isn't feasible, the caller must already
2087 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
2088 /// hang forever. See ValidateBufferCollectionToken() to check token
2089 /// validity first if the token isn't already known to be (is/was) valid.
2090 pub fn r#sync(
2091 &self,
2092 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
2093 BufferCollectionProxyInterface::r#sync(self)
2094 }
2095
2096 /// On a BufferCollectionToken channel:
2097 ///
2098 /// Normally a participant will convert a BufferCollectionToken into a
2099 /// BufferCollection view, but a participant is also free to Close() the
2100 /// token (and then close the channel immediately or shortly later in
2101 /// response to server closing its end), which avoids causing logical buffer
2102 /// collection failure. Â Normally an unexpected token channel close will
2103 /// cause logical buffer collection failure (the only exceptions being
2104 /// certain cases involving AttachToken() or SetDispensable()).
2105 ///
2106 /// On a BufferCollection channel:
2107 ///
2108 /// By default the server handles unexpected failure of a BufferCollection
2109 /// by failing the whole logical buffer collection. Partly this is to
2110 /// expedite closing VMO handles to reclaim memory when any participant
2111 /// fails. If a participant would like to cleanly close a BufferCollection
2112 /// view without causing logical buffer collection failure, the participant
2113 /// can send Close() before closing the client end of the BufferCollection
2114 /// channel. If this is the last BufferCollection view, the logical buffer
2115 /// collection will still go away. The Close() can occur before or after
2116 /// SetConstraints(). If before SetConstraints(), the buffer collection
2117 /// won't require constraints from this node in order to allocate. If
2118 /// after SetConstraints(), the constraints are retained and aggregated
2119 /// along with any subsequent logical allocation(s), despite the lack of
2120 /// channel connection.
2121 ///
2122 /// On a BufferCollectionTokenGroup channel:
2123 ///
2124 /// By default, unexpected failure of a BufferCollectionTokenGroup will
2125 /// trigger failure of the logical BufferCollectionTokenGroup and will
2126 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
2127 /// channel without failing the logical group or propagating failure, send
2128 /// Close() before closing the channel client endpoint.
2129 ///
2130 /// If Close() occurs before AllChildrenPresent(), the logical buffer
2131 /// collection will still fail despite the Close() (because sysmem can't be
2132 /// sure whether all relevant children were created, so it's ambiguous
2133 /// whether all relevant constraints will be provided to sysmem). If
2134 /// Close() occurs after AllChildrenPresent(), the children and all their
2135 /// constraints remain intact (just as they would if the
2136 /// BufferCollectionTokenGroup channel had remained open), and the close
2137 /// doesn't trigger or propagate failure.
2138 pub fn r#close(&self) -> Result<(), fidl::Error> {
2139 BufferCollectionProxyInterface::r#close(self)
2140 }
2141
2142 /// Set a name for VMOs in this buffer collection. The name may be truncated
2143 /// shorter. The name only affects VMOs allocated after it's set - this call
2144 /// does not rename existing VMOs. If multiple clients set different names
2145 /// then the larger priority value will win.
2146 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
2147 BufferCollectionProxyInterface::r#set_name(self, priority, name)
2148 }
2149
2150 /// Set information about the current client that can be used by sysmem to
2151 /// help debug leaking memory and hangs waiting for constraints. |name| can
2152 /// be an arbitrary string, but the current process name (see
2153 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
2154 /// arbitrary id, but the current process ID (see
2155 /// fsl::GetCurrentProcessKoid()) is a good default.
2156 ///
2157 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
2158 /// indicate which client is closing their channel first, leading to
2159 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
2160 /// over, but if happening earlier than expected, the
2161 /// client-channel-specific name can help diagnose where the failure is
2162 /// first coming from, from sysmem's point of view).
2163 ///
2164 /// By default (unless overriden by this message or using
2165 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
2166 /// parent Node at the time the child Node is created. While this can be
2167 /// better than nothing, it's often better for each participant to use
2168 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
2169 /// info directly relevant to the current client. Also, SetVerboseLogging()
2170 /// can be used to help disambiguate if a Node is suspected of having info
2171 /// that was copied from its parent.
2172 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
2173 BufferCollectionProxyInterface::r#set_debug_client_info(self, name, id)
2174 }
2175
2176 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
2177 /// after creating a collection. Clients can call this method to change
2178 /// when the log is printed. If multiple client set the deadline, it's
2179 /// unspecified which deadline will take effect.
2180 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
2181 BufferCollectionProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
2182 }
2183
2184 /// Verbose logging includes constraints set via SetConstraints() from each
2185 /// client along with info set via SetDebugClientInfo() and the structure of
2186 /// the tree of Node(s).
2187 ///
2188 /// Normally sysmem prints only a single line complaint when aggregation
2189 /// fails, with just the specific detailed reason that aggregation failed,
2190 /// with minimal context. While this is often enough to diagnose a problem
2191 /// if only a small change was made and the system had been working before
2192 /// the small change, it's often not particularly helpful for getting a new
2193 /// buffer collection to work for the first time. Especially with more
2194 /// complex trees of nodes, involving things like AttachToken(),
2195 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
2196 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
2197 /// looks like and why it's failing a logical allocation, or why a tree or
2198 /// sub-tree is failing sooner than expected.
2199 ///
2200 /// The intent of the extra logging is to be acceptable from a performance
2201 /// point of view, if only enabled on a low number of buffer collections.
2202 /// If we're not tracking down a bug, we shouldn't send this message.
2203 ///
2204 /// If too many participants leave verbose logging enabled, we may end up
2205 /// needing to require that system-wide sysmem verbose logging be permitted
2206 /// via some other setting, to avoid sysmem spamming the log too much due to
2207 /// this message.
2208 ///
2209 /// This may be a NOP for some nodes due to intentional policy associated
2210 /// with the node, if we don't trust a node enough to let it turn on verbose
2211 /// logging.
2212 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
2213 BufferCollectionProxyInterface::r#set_verbose_logging(self)
2214 }
2215
2216 /// This gets an event handle that can be used as a parameter to
2217 /// IsAlternateFor() called on any Node. The client will not be granted the
2218 /// right to signal this event, as this handle should only be used as proof
2219 /// that the client obtained this handle from this Node.
2220 ///
2221 /// Because this is a get not a set, no Sync() is needed between the
2222 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
2223 /// potentially being on different channels.
2224 ///
2225 /// See also IsAlternateFor().
2226 pub fn r#get_node_ref(
2227 &self,
2228 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
2229 {
2230 BufferCollectionProxyInterface::r#get_node_ref(self)
2231 }
2232
2233 /// This checks whether the calling node is in a subtree rooted at a
2234 /// different child token of a common parent BufferCollectionTokenGroup, in
2235 /// relation to the passed-in node_ref.
2236 ///
2237 /// This call is for assisting with admission control de-duplication, and
2238 /// with debugging.
2239 ///
2240 /// The node_ref must be obtained using GetNodeRef() of a
2241 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
2242 ///
2243 /// The node_ref can be a duplicated handle; it's not necessary to call
2244 /// GetNodeRef() for every call to IsAlternateFor().
2245 ///
2246 /// If a calling token may not actually be a valid token at all due to
2247 /// a potentially hostile/untrusted provider of the token, call
2248 /// ValidateBufferCollectionToken() first instead of potentially getting
2249 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
2250 /// token not being a real token (not really talking to sysmem). Another
2251 /// option is to call BindSharedCollection with this token first which also
2252 /// validates the token along with converting it to a BufferCollection, then
2253 /// call BufferCollection IsAlternateFor().
2254 ///
2255 /// error values:
2256 ///
2257 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
2258 /// buffer collection as the calling Node. Before logical allocation and
2259 /// within the same logical allocation sub-tree, this essentially means that
2260 /// the node_ref was never part of this logical buffer collection, since
2261 /// before logical allocation all node_refs that come into existence remain
2262 /// in existence at least until logical allocation (including Node(s) that
2263 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
2264 /// to be returned, this Node's channel needs to still be connected server
2265 /// side, which won't be the case if the whole logical allocation has
2266 /// failed. After logical allocation or in a different logical allocation
2267 /// sub-tree there are additional potential reasons for this error. For
2268 /// example a different logical allocation (separated from this Node(s)
2269 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
2270 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
2271 /// exist and may select a different child sub-tree than the sub-tree the
2272 /// node_ref is in causing deletion of the node_ref Node. The only time
2273 /// sysmem keeps a Node around after that Node has no corresponding channel
2274 /// is when Close() is used and the Node's sub-tree has not yet failed.
2275 /// Another reason for this error is if the node_ref is an eventpair handle
2276 /// with sufficient rights, but isn't actually a real node_ref obtained from
2277 /// GetNodeRef().
2278 ///
2279 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
2280 /// eventpair handle, or doesn't have the needed rights expected on a real
2281 /// node_ref.
2282 ///
2283 /// No other failing status codes are returned by this call. However,
2284 /// sysmem may add additional codes in future, so the client should have
2285 /// sensible default handling for any failing status code.
2286 ///
2287 /// On success, is_alternate has the following meaning:
2288 /// * true - The first parent node in common between the calling node and
2289 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
2290 /// the calling Node and the node_ref Node will _not_ have both their
2291 /// constraints apply - rather sysmem will choose one or the other of
2292 /// the constraints - never both. This is because only one child of
2293 /// a BufferCollectionTokenGroup is selected during logical allocation,
2294 /// with only that one child's sub-tree contributing to constraints
2295 /// aggregation.
2296 /// * false - The first parent node in common between the calling Node and
2297 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
2298 /// this means the first parent node in common is a
2299 /// BufferCollectionToken or BufferCollection (regardless of not
2300 /// Close()ed or Close()ed). This means that the calling Node and the
2301 /// node_ref Node _may_ have both their constraints apply during
2302 /// constraints aggregation of the logical allocation, if both Node(s)
2303 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
2304 /// In this case, there is no BufferCollectionTokenGroup that will
2305 /// directly prevent the two Node(s) from both being selected and their
2306 /// constraints both aggregated, but even when false, one or both
2307 /// Node(s) may still be eliminated from consideration if one or both
2308 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
2309 /// which selects a child sub-tree other than the sub-tree containing
2310 /// the calling Node or node_ref Node.
2311 pub fn r#is_alternate_for(
2312 &self,
2313 mut node_ref: fidl::Event,
2314 ) -> fidl::client::QueryResponseFut<
2315 NodeIsAlternateForResult,
2316 fidl::encoding::DefaultFuchsiaResourceDialect,
2317 > {
2318 BufferCollectionProxyInterface::r#is_alternate_for(self, node_ref)
2319 }
2320
2321 /// Provide BufferCollectionConstraints to the logical BufferCollection.
2322 ///
2323 /// A participant may only call SetConstraints() once.
2324 ///
2325 /// Sometimes the initiator is a participant only in the sense of wanting to
2326 /// keep an eye on success/failure to populate with buffers, and zx.Status
2327 /// on failure. In that case, `has_constraints` can be false, and
2328 /// `constraints` will be ignored.
2329 ///
2330 /// VMO handles will not be provided to the client that sends null
2331 /// constraints - that can be intentional for an initiator that doesn't need
2332 /// VMO handles. Not having VMO handles doesn't prevent the initator from
2333 /// adjusting which portion of a buffer is considered valid and similar, but
2334 /// the initiator can't hold a VMO handle open to prevent the logical
2335 /// BufferCollection from cleaning up if the logical BufferCollection needs
2336 /// to go away regardless of the initiator's degree of involvement for
2337 /// whatever reason.
2338 ///
2339 /// For population of buffers to be attempted, all holders of a
2340 /// BufferCollection client channel need to call SetConstraints() before
2341 /// sysmem will attempt to allocate buffers.
2342 ///
2343 /// `has_constraints` if false, the constraints are effectively null, and
2344 /// `constraints` are ignored. The sender of null constraints won't get any
2345 /// VMO handles in BufferCollectionInfo, but can still find out how many
2346 /// buffers were allocated and can still refer to buffers by their
2347 /// buffer_index.
2348 ///
2349 /// `constraints` are constraints on the buffer collection.
2350 pub fn r#set_constraints(
2351 &self,
2352 mut has_constraints: bool,
2353 mut constraints: &BufferCollectionConstraints,
2354 ) -> Result<(), fidl::Error> {
2355 BufferCollectionProxyInterface::r#set_constraints(self, has_constraints, constraints)
2356 }
2357
2358 /// This request completes when buffers have been allocated, responds with
2359 /// some failure detail if allocation has been attempted but failed.
2360 ///
2361 /// The following must occur before buffers will be allocated:
2362 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
2363 /// must be turned in via BindSharedCollection().
2364 /// * All BufferCollection(s) of the logical BufferCollection must have
2365 /// had SetConstraints() sent to them.
2366 ///
2367 /// Returns `ZX_OK` if successful.
2368 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
2369 /// fulfilled due to resource exhaustion.
2370 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
2371 /// obtain the buffers it requested.
2372 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
2373 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
2374 /// satisfied, perhaps due to hardware limitations.
2375 ///
2376 /// `buffer_collection_info` has the VMO handles and other related info.
2377 pub fn r#wait_for_buffers_allocated(
2378 &self,
2379 ) -> fidl::client::QueryResponseFut<
2380 (i32, BufferCollectionInfo2),
2381 fidl::encoding::DefaultFuchsiaResourceDialect,
2382 > {
2383 BufferCollectionProxyInterface::r#wait_for_buffers_allocated(self)
2384 }
2385
2386 /// This returns the same result code as WaitForBuffersAllocated if the
2387 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
2388 /// if WaitForBuffersAllocated would block.
2389 pub fn r#check_buffers_allocated(
2390 &self,
2391 ) -> fidl::client::QueryResponseFut<i32, fidl::encoding::DefaultFuchsiaResourceDialect> {
2392 BufferCollectionProxyInterface::r#check_buffers_allocated(self)
2393 }
2394
2395 pub fn r#set_constraints_aux_buffers(
2396 &self,
2397 mut constraints: &BufferCollectionConstraintsAuxBuffers,
2398 ) -> Result<(), fidl::Error> {
2399 BufferCollectionProxyInterface::r#set_constraints_aux_buffers(self, constraints)
2400 }
2401
2402 pub fn r#get_aux_buffers(
2403 &self,
2404 ) -> fidl::client::QueryResponseFut<
2405 (i32, BufferCollectionInfo2),
2406 fidl::encoding::DefaultFuchsiaResourceDialect,
2407 > {
2408 BufferCollectionProxyInterface::r#get_aux_buffers(self)
2409 }
2410
2411 /// Create a new token, for trying to add a new participant to an existing
2412 /// collection, if the existing collection's buffer counts, constraints,
2413 /// and participants allow.
2414 ///
2415 /// This can be useful in replacing a failed participant, and/or in
2416 /// adding/re-adding a participant after buffers have already been
2417 /// allocated.
2418 ///
2419 /// Failure of an attached token / collection does not propagate to the
2420 /// parent of the attached token. Failure does propagate from a normal
2421 /// child of a dispensable token to the dispensable token. Failure
2422 /// of a child is blocked from reaching its parent if the child is attached,
2423 /// or if the child is dispensable and the failure occurred after logical
2424 /// allocation.
2425 ///
2426 /// An initiator may in some scenarios choose to initially use a dispensable
2427 /// token for a given instance of a participant, and then later if the first
2428 /// instance of that participant fails, a new second instance of that
2429 /// participant my be given a token created with AttachToken().
2430 ///
2431 /// From the point of view of the client end of the BufferCollectionToken
2432 /// channel, the token acts like any other token. The client can
2433 /// Duplicate() the token as needed, and can send the token to a different
2434 /// process. The token should be converted to a BufferCollection channel
2435 /// as normal by calling BindSharedCollection(). SetConstraints() should
2436 /// be called on that BufferCollection channel.
2437 ///
2438 /// A success result from WaitForBuffersAllocated() means the new
2439 /// participant's constraints were satisfiable using the already-existing
2440 /// buffer collection, the already-established BufferCollectionInfo
2441 /// including image format constraints, and the already-existing other
2442 /// participants and their buffer counts. A failure result means the new
2443 /// participant's constraints cannot be satisfied using the existing
2444 /// buffer collection and its already-logically-allocated participants.
2445 /// Creating a new collection instead may allow all participant's
2446 /// constraints to be satisfied, assuming SetDispensable() is used in place
2447 /// of AttachToken(), or a normal token is used.
2448 ///
2449 /// A token created with AttachToken() performs constraints aggregation with
2450 /// all constraints currently in effect on the buffer collection, plus the
2451 /// attached token under consideration plus child tokens under the attached
2452 /// token which are not themselves an attached token or under such a token.
2453 ///
2454 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
2455 /// first-come first-served, but a child can't logically allocate before
2456 /// all its parents have sent SetConstraints().
2457 ///
2458 /// See also SetDispensable(), which in contrast to AttachToken(), has the
2459 /// created token + children participate in constraints aggregation along
2460 /// with its parent.
2461 ///
2462 /// The newly created token needs to be Sync()ed to sysmem before the new
2463 /// token can be passed to BindSharedCollection(). The Sync() of the new
2464 /// token can be accomplished with BufferCollection.Sync() on this
2465 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
2466 /// token also works. A BufferCollectionToken.Sync() can be started after
2467 /// any BufferCollectionToken.Duplicate() messages have been sent via the
2468 /// newly created token, to also sync those additional tokens to sysmem
2469 /// using a single round-trip.
2470 ///
2471 /// These values for rights_attenuation_mask result in no attenuation (note
2472 /// that 0 is not on this list; 0 will output an ERROR to the system log
2473 /// to help diagnose the bug in client code):
2474 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
2475 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
2476 pub fn r#attach_token(
2477 &self,
2478 mut rights_attenuation_mask: u32,
2479 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
2480 ) -> Result<(), fidl::Error> {
2481 BufferCollectionProxyInterface::r#attach_token(self, rights_attenuation_mask, token_request)
2482 }
2483
2484 /// AttachLifetimeTracking:
2485 ///
2486 /// AttachLifetimeTracking() is intended to allow a client to wait until an
2487 /// old logical buffer collection is fully or mostly deallocated before
2488 /// attempting allocation of a new logical buffer collection.
2489 ///
2490 /// Attach an eventpair endpoint to the logical buffer collection, so that
2491 /// the server_end will be closed when the number of buffers allocated
2492 /// drops to 'buffers_remaining'. The server_end won't close until after
2493 /// logical allocation has completed.
2494 ///
2495 /// If logical allocation fails, such as for an attached sub-tree (using
2496 /// AttachToken()), the server_end will close during that failure regardless
2497 /// of the number of buffers potenitally allocated in the overall logical
2498 /// buffer collection.
2499 ///
2500 /// The lifetime signalled by this event includes asynchronous cleanup of
2501 /// allocated buffers, and this asynchronous cleanup cannot occur until all
2502 /// holders of VMO handles to the buffers have closed those VMO handles.
2503 /// Therefore clients should take care not to become blocked forever waiting
2504 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
2505 /// participants using the logical buffer collection are less trusted or
2506 /// less reliable.
2507 ///
2508 /// The buffers_remaining parameter allows waiting for all but
2509 /// buffers_remaining buffers to be fully deallocated. This can be useful
2510 /// in situations where a known number of buffers are intentionally not
2511 /// closed so that the data can continue to be used, such as for keeping the
2512 /// last available video picture displayed in the UI even if the video
2513 /// stream was using protected output buffers. It's outside the scope of
2514 /// the BufferCollection interface (at least for now) to determine how many
2515 /// buffers may be held without closing, but it'll typically be in the range
2516 /// 0-2.
2517 ///
2518 /// This mechanism is meant to be compatible with other protocols providing
2519 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
2520 /// same event can be sent to more than one AttachLifetimeTracking(), and
2521 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
2522 /// over conditions are met (all holders of duplicates have closed their
2523 /// handle(s)).
2524 ///
2525 /// There is no way to cancel an attach. Closing the client end of the
2526 /// eventpair doesn't subtract from the number of pending attach(es).
2527 ///
2528 /// Closing the client's end doesn't result in any action by the server.
2529 /// If the server listens to events from the client end at all, it is for
2530 /// debug logging only.
2531 ///
2532 /// The server intentionally doesn't "trust" any bits signalled by the
2533 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
2534 /// which can't be triggered early, and is only triggered when all handles
2535 /// to server_end are closed. No meaning is associated with any of the
2536 /// other signal bits, and clients should functionally ignore any other
2537 /// signal bits on either end of the eventpair or its peer.
2538 ///
2539 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
2540 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
2541 /// transfer without causing CodecFactory channel failure).
2542 pub fn r#attach_lifetime_tracking(
2543 &self,
2544 mut server_end: fidl::EventPair,
2545 mut buffers_remaining: u32,
2546 ) -> Result<(), fidl::Error> {
2547 BufferCollectionProxyInterface::r#attach_lifetime_tracking(
2548 self,
2549 server_end,
2550 buffers_remaining,
2551 )
2552 }
2553}
2554
2555impl BufferCollectionProxyInterface for BufferCollectionProxy {
2556 type SyncResponseFut =
2557 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
2558 fn r#sync(&self) -> Self::SyncResponseFut {
2559 fn _decode(
2560 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2561 ) -> Result<(), fidl::Error> {
2562 let _response = fidl::client::decode_transaction_body::<
2563 fidl::encoding::EmptyPayload,
2564 fidl::encoding::DefaultFuchsiaResourceDialect,
2565 0x4577e238ae26291,
2566 >(_buf?)?;
2567 Ok(_response)
2568 }
2569 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
2570 (),
2571 0x4577e238ae26291,
2572 fidl::encoding::DynamicFlags::empty(),
2573 _decode,
2574 )
2575 }
2576
2577 fn r#close(&self) -> Result<(), fidl::Error> {
2578 self.client.send::<fidl::encoding::EmptyPayload>(
2579 (),
2580 0x5b1d7a4f5681fca7,
2581 fidl::encoding::DynamicFlags::empty(),
2582 )
2583 }
2584
2585 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
2586 self.client.send::<NodeSetNameRequest>(
2587 (priority, name),
2588 0x77a41bb6217e2443,
2589 fidl::encoding::DynamicFlags::empty(),
2590 )
2591 }
2592
2593 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
2594 self.client.send::<NodeSetDebugClientInfoRequest>(
2595 (name, id),
2596 0x7275759070eb5ee2,
2597 fidl::encoding::DynamicFlags::empty(),
2598 )
2599 }
2600
2601 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
2602 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
2603 (deadline,),
2604 0x46d38f4772638867,
2605 fidl::encoding::DynamicFlags::empty(),
2606 )
2607 }
2608
2609 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
2610 self.client.send::<fidl::encoding::EmptyPayload>(
2611 (),
2612 0x6bfbe2cf1701d288,
2613 fidl::encoding::DynamicFlags::empty(),
2614 )
2615 }
2616
2617 type GetNodeRefResponseFut =
2618 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
2619 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
2620 fn _decode(
2621 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2622 ) -> Result<fidl::Event, fidl::Error> {
2623 let _response = fidl::client::decode_transaction_body::<
2624 NodeGetNodeRefResponse,
2625 fidl::encoding::DefaultFuchsiaResourceDialect,
2626 0x467b7c75c35c3b84,
2627 >(_buf?)?;
2628 Ok(_response.node_ref)
2629 }
2630 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
2631 (),
2632 0x467b7c75c35c3b84,
2633 fidl::encoding::DynamicFlags::empty(),
2634 _decode,
2635 )
2636 }
2637
2638 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
2639 NodeIsAlternateForResult,
2640 fidl::encoding::DefaultFuchsiaResourceDialect,
2641 >;
2642 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
2643 fn _decode(
2644 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2645 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
2646 let _response = fidl::client::decode_transaction_body::<
2647 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
2648 fidl::encoding::DefaultFuchsiaResourceDialect,
2649 0x33a2a7aff2776c07,
2650 >(_buf?)?;
2651 Ok(_response.map(|x| x.is_alternate))
2652 }
2653 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
2654 (node_ref,),
2655 0x33a2a7aff2776c07,
2656 fidl::encoding::DynamicFlags::empty(),
2657 _decode,
2658 )
2659 }
2660
2661 fn r#set_constraints(
2662 &self,
2663 mut has_constraints: bool,
2664 mut constraints: &BufferCollectionConstraints,
2665 ) -> Result<(), fidl::Error> {
2666 self.client.send::<BufferCollectionSetConstraintsRequest>(
2667 (has_constraints, constraints),
2668 0x4d9c3406c213227b,
2669 fidl::encoding::DynamicFlags::empty(),
2670 )
2671 }
2672
2673 type WaitForBuffersAllocatedResponseFut = fidl::client::QueryResponseFut<
2674 (i32, BufferCollectionInfo2),
2675 fidl::encoding::DefaultFuchsiaResourceDialect,
2676 >;
2677 fn r#wait_for_buffers_allocated(&self) -> Self::WaitForBuffersAllocatedResponseFut {
2678 fn _decode(
2679 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2680 ) -> Result<(i32, BufferCollectionInfo2), fidl::Error> {
2681 let _response = fidl::client::decode_transaction_body::<
2682 BufferCollectionWaitForBuffersAllocatedResponse,
2683 fidl::encoding::DefaultFuchsiaResourceDialect,
2684 0x714667ea2a29a3a2,
2685 >(_buf?)?;
2686 Ok((_response.status, _response.buffer_collection_info))
2687 }
2688 self.client
2689 .send_query_and_decode::<fidl::encoding::EmptyPayload, (i32, BufferCollectionInfo2)>(
2690 (),
2691 0x714667ea2a29a3a2,
2692 fidl::encoding::DynamicFlags::empty(),
2693 _decode,
2694 )
2695 }
2696
2697 type CheckBuffersAllocatedResponseFut =
2698 fidl::client::QueryResponseFut<i32, fidl::encoding::DefaultFuchsiaResourceDialect>;
2699 fn r#check_buffers_allocated(&self) -> Self::CheckBuffersAllocatedResponseFut {
2700 fn _decode(
2701 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2702 ) -> Result<i32, fidl::Error> {
2703 let _response = fidl::client::decode_transaction_body::<
2704 BufferCollectionCheckBuffersAllocatedResponse,
2705 fidl::encoding::DefaultFuchsiaResourceDialect,
2706 0x245bb81f79189e9,
2707 >(_buf?)?;
2708 Ok(_response.status)
2709 }
2710 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, i32>(
2711 (),
2712 0x245bb81f79189e9,
2713 fidl::encoding::DynamicFlags::empty(),
2714 _decode,
2715 )
2716 }
2717
2718 fn r#set_constraints_aux_buffers(
2719 &self,
2720 mut constraints: &BufferCollectionConstraintsAuxBuffers,
2721 ) -> Result<(), fidl::Error> {
2722 self.client.send::<BufferCollectionSetConstraintsAuxBuffersRequest>(
2723 (constraints,),
2724 0x1ad80e63c090d817,
2725 fidl::encoding::DynamicFlags::empty(),
2726 )
2727 }
2728
2729 type GetAuxBuffersResponseFut = fidl::client::QueryResponseFut<
2730 (i32, BufferCollectionInfo2),
2731 fidl::encoding::DefaultFuchsiaResourceDialect,
2732 >;
2733 fn r#get_aux_buffers(&self) -> Self::GetAuxBuffersResponseFut {
2734 fn _decode(
2735 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2736 ) -> Result<(i32, BufferCollectionInfo2), fidl::Error> {
2737 let _response = fidl::client::decode_transaction_body::<
2738 BufferCollectionGetAuxBuffersResponse,
2739 fidl::encoding::DefaultFuchsiaResourceDialect,
2740 0x6c6cac6000a29a55,
2741 >(_buf?)?;
2742 Ok((_response.status, _response.buffer_collection_info_aux_buffers))
2743 }
2744 self.client
2745 .send_query_and_decode::<fidl::encoding::EmptyPayload, (i32, BufferCollectionInfo2)>(
2746 (),
2747 0x6c6cac6000a29a55,
2748 fidl::encoding::DynamicFlags::empty(),
2749 _decode,
2750 )
2751 }
2752
2753 fn r#attach_token(
2754 &self,
2755 mut rights_attenuation_mask: u32,
2756 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
2757 ) -> Result<(), fidl::Error> {
2758 self.client.send::<BufferCollectionAttachTokenRequest>(
2759 (rights_attenuation_mask, token_request),
2760 0x6f5adcca4ac7443e,
2761 fidl::encoding::DynamicFlags::empty(),
2762 )
2763 }
2764
2765 fn r#attach_lifetime_tracking(
2766 &self,
2767 mut server_end: fidl::EventPair,
2768 mut buffers_remaining: u32,
2769 ) -> Result<(), fidl::Error> {
2770 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
2771 (server_end, buffers_remaining),
2772 0x170d0f1d89d50989,
2773 fidl::encoding::DynamicFlags::empty(),
2774 )
2775 }
2776}
2777
2778pub struct BufferCollectionEventStream {
2779 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
2780}
2781
2782impl std::marker::Unpin for BufferCollectionEventStream {}
2783
2784impl futures::stream::FusedStream for BufferCollectionEventStream {
2785 fn is_terminated(&self) -> bool {
2786 self.event_receiver.is_terminated()
2787 }
2788}
2789
2790impl futures::Stream for BufferCollectionEventStream {
2791 type Item = Result<BufferCollectionEvent, fidl::Error>;
2792
2793 fn poll_next(
2794 mut self: std::pin::Pin<&mut Self>,
2795 cx: &mut std::task::Context<'_>,
2796 ) -> std::task::Poll<Option<Self::Item>> {
2797 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
2798 &mut self.event_receiver,
2799 cx
2800 )?) {
2801 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionEvent::decode(buf))),
2802 None => std::task::Poll::Ready(None),
2803 }
2804 }
2805}
2806
2807#[derive(Debug)]
2808pub enum BufferCollectionEvent {}
2809
2810impl BufferCollectionEvent {
2811 /// Decodes a message buffer as a [`BufferCollectionEvent`].
2812 fn decode(
2813 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
2814 ) -> Result<BufferCollectionEvent, fidl::Error> {
2815 let (bytes, _handles) = buf.split_mut();
2816 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
2817 debug_assert_eq!(tx_header.tx_id, 0);
2818 match tx_header.ordinal {
2819 _ => Err(fidl::Error::UnknownOrdinal {
2820 ordinal: tx_header.ordinal,
2821 protocol_name:
2822 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
2823 }),
2824 }
2825 }
2826}
2827
2828/// A Stream of incoming requests for fuchsia.sysmem/BufferCollection.
2829pub struct BufferCollectionRequestStream {
2830 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2831 is_terminated: bool,
2832}
2833
2834impl std::marker::Unpin for BufferCollectionRequestStream {}
2835
2836impl futures::stream::FusedStream for BufferCollectionRequestStream {
2837 fn is_terminated(&self) -> bool {
2838 self.is_terminated
2839 }
2840}
2841
2842impl fidl::endpoints::RequestStream for BufferCollectionRequestStream {
2843 type Protocol = BufferCollectionMarker;
2844 type ControlHandle = BufferCollectionControlHandle;
2845
2846 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
2847 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
2848 }
2849
2850 fn control_handle(&self) -> Self::ControlHandle {
2851 BufferCollectionControlHandle { inner: self.inner.clone() }
2852 }
2853
2854 fn into_inner(
2855 self,
2856 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
2857 {
2858 (self.inner, self.is_terminated)
2859 }
2860
2861 fn from_inner(
2862 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2863 is_terminated: bool,
2864 ) -> Self {
2865 Self { inner, is_terminated }
2866 }
2867}
2868
2869impl futures::Stream for BufferCollectionRequestStream {
2870 type Item = Result<BufferCollectionRequest, fidl::Error>;
2871
2872 fn poll_next(
2873 mut self: std::pin::Pin<&mut Self>,
2874 cx: &mut std::task::Context<'_>,
2875 ) -> std::task::Poll<Option<Self::Item>> {
2876 let this = &mut *self;
2877 if this.inner.check_shutdown(cx) {
2878 this.is_terminated = true;
2879 return std::task::Poll::Ready(None);
2880 }
2881 if this.is_terminated {
2882 panic!("polled BufferCollectionRequestStream after completion");
2883 }
2884 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
2885 |bytes, handles| {
2886 match this.inner.channel().read_etc(cx, bytes, handles) {
2887 std::task::Poll::Ready(Ok(())) => {}
2888 std::task::Poll::Pending => return std::task::Poll::Pending,
2889 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
2890 this.is_terminated = true;
2891 return std::task::Poll::Ready(None);
2892 }
2893 std::task::Poll::Ready(Err(e)) => {
2894 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
2895 e.into(),
2896 ))))
2897 }
2898 }
2899
2900 // A message has been received from the channel
2901 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
2902
2903 std::task::Poll::Ready(Some(match header.ordinal {
2904 0x4577e238ae26291 => {
2905 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2906 let mut req = fidl::new_empty!(
2907 fidl::encoding::EmptyPayload,
2908 fidl::encoding::DefaultFuchsiaResourceDialect
2909 );
2910 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2911 let control_handle =
2912 BufferCollectionControlHandle { inner: this.inner.clone() };
2913 Ok(BufferCollectionRequest::Sync {
2914 responder: BufferCollectionSyncResponder {
2915 control_handle: std::mem::ManuallyDrop::new(control_handle),
2916 tx_id: header.tx_id,
2917 },
2918 })
2919 }
2920 0x5b1d7a4f5681fca7 => {
2921 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2922 let mut req = fidl::new_empty!(
2923 fidl::encoding::EmptyPayload,
2924 fidl::encoding::DefaultFuchsiaResourceDialect
2925 );
2926 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2927 let control_handle =
2928 BufferCollectionControlHandle { inner: this.inner.clone() };
2929 Ok(BufferCollectionRequest::Close { control_handle })
2930 }
2931 0x77a41bb6217e2443 => {
2932 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2933 let mut req = fidl::new_empty!(
2934 NodeSetNameRequest,
2935 fidl::encoding::DefaultFuchsiaResourceDialect
2936 );
2937 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
2938 let control_handle =
2939 BufferCollectionControlHandle { inner: this.inner.clone() };
2940 Ok(BufferCollectionRequest::SetName {
2941 priority: req.priority,
2942 name: req.name,
2943
2944 control_handle,
2945 })
2946 }
2947 0x7275759070eb5ee2 => {
2948 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2949 let mut req = fidl::new_empty!(
2950 NodeSetDebugClientInfoRequest,
2951 fidl::encoding::DefaultFuchsiaResourceDialect
2952 );
2953 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
2954 let control_handle =
2955 BufferCollectionControlHandle { inner: this.inner.clone() };
2956 Ok(BufferCollectionRequest::SetDebugClientInfo {
2957 name: req.name,
2958 id: req.id,
2959
2960 control_handle,
2961 })
2962 }
2963 0x46d38f4772638867 => {
2964 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2965 let mut req = fidl::new_empty!(
2966 NodeSetDebugTimeoutLogDeadlineRequest,
2967 fidl::encoding::DefaultFuchsiaResourceDialect
2968 );
2969 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
2970 let control_handle =
2971 BufferCollectionControlHandle { inner: this.inner.clone() };
2972 Ok(BufferCollectionRequest::SetDebugTimeoutLogDeadline {
2973 deadline: req.deadline,
2974
2975 control_handle,
2976 })
2977 }
2978 0x6bfbe2cf1701d288 => {
2979 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2980 let mut req = fidl::new_empty!(
2981 fidl::encoding::EmptyPayload,
2982 fidl::encoding::DefaultFuchsiaResourceDialect
2983 );
2984 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2985 let control_handle =
2986 BufferCollectionControlHandle { inner: this.inner.clone() };
2987 Ok(BufferCollectionRequest::SetVerboseLogging { control_handle })
2988 }
2989 0x467b7c75c35c3b84 => {
2990 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2991 let mut req = fidl::new_empty!(
2992 fidl::encoding::EmptyPayload,
2993 fidl::encoding::DefaultFuchsiaResourceDialect
2994 );
2995 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2996 let control_handle =
2997 BufferCollectionControlHandle { inner: this.inner.clone() };
2998 Ok(BufferCollectionRequest::GetNodeRef {
2999 responder: BufferCollectionGetNodeRefResponder {
3000 control_handle: std::mem::ManuallyDrop::new(control_handle),
3001 tx_id: header.tx_id,
3002 },
3003 })
3004 }
3005 0x33a2a7aff2776c07 => {
3006 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
3007 let mut req = fidl::new_empty!(
3008 NodeIsAlternateForRequest,
3009 fidl::encoding::DefaultFuchsiaResourceDialect
3010 );
3011 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
3012 let control_handle =
3013 BufferCollectionControlHandle { inner: this.inner.clone() };
3014 Ok(BufferCollectionRequest::IsAlternateFor {
3015 node_ref: req.node_ref,
3016
3017 responder: BufferCollectionIsAlternateForResponder {
3018 control_handle: std::mem::ManuallyDrop::new(control_handle),
3019 tx_id: header.tx_id,
3020 },
3021 })
3022 }
3023 0x4d9c3406c213227b => {
3024 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
3025 let mut req = fidl::new_empty!(
3026 BufferCollectionSetConstraintsRequest,
3027 fidl::encoding::DefaultFuchsiaResourceDialect
3028 );
3029 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionSetConstraintsRequest>(&header, _body_bytes, handles, &mut req)?;
3030 let control_handle =
3031 BufferCollectionControlHandle { inner: this.inner.clone() };
3032 Ok(BufferCollectionRequest::SetConstraints {
3033 has_constraints: req.has_constraints,
3034 constraints: req.constraints,
3035
3036 control_handle,
3037 })
3038 }
3039 0x714667ea2a29a3a2 => {
3040 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
3041 let mut req = fidl::new_empty!(
3042 fidl::encoding::EmptyPayload,
3043 fidl::encoding::DefaultFuchsiaResourceDialect
3044 );
3045 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
3046 let control_handle =
3047 BufferCollectionControlHandle { inner: this.inner.clone() };
3048 Ok(BufferCollectionRequest::WaitForBuffersAllocated {
3049 responder: BufferCollectionWaitForBuffersAllocatedResponder {
3050 control_handle: std::mem::ManuallyDrop::new(control_handle),
3051 tx_id: header.tx_id,
3052 },
3053 })
3054 }
3055 0x245bb81f79189e9 => {
3056 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
3057 let mut req = fidl::new_empty!(
3058 fidl::encoding::EmptyPayload,
3059 fidl::encoding::DefaultFuchsiaResourceDialect
3060 );
3061 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
3062 let control_handle =
3063 BufferCollectionControlHandle { inner: this.inner.clone() };
3064 Ok(BufferCollectionRequest::CheckBuffersAllocated {
3065 responder: BufferCollectionCheckBuffersAllocatedResponder {
3066 control_handle: std::mem::ManuallyDrop::new(control_handle),
3067 tx_id: header.tx_id,
3068 },
3069 })
3070 }
3071 0x1ad80e63c090d817 => {
3072 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
3073 let mut req = fidl::new_empty!(
3074 BufferCollectionSetConstraintsAuxBuffersRequest,
3075 fidl::encoding::DefaultFuchsiaResourceDialect
3076 );
3077 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionSetConstraintsAuxBuffersRequest>(&header, _body_bytes, handles, &mut req)?;
3078 let control_handle =
3079 BufferCollectionControlHandle { inner: this.inner.clone() };
3080 Ok(BufferCollectionRequest::SetConstraintsAuxBuffers {
3081 constraints: req.constraints,
3082
3083 control_handle,
3084 })
3085 }
3086 0x6c6cac6000a29a55 => {
3087 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
3088 let mut req = fidl::new_empty!(
3089 fidl::encoding::EmptyPayload,
3090 fidl::encoding::DefaultFuchsiaResourceDialect
3091 );
3092 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
3093 let control_handle =
3094 BufferCollectionControlHandle { inner: this.inner.clone() };
3095 Ok(BufferCollectionRequest::GetAuxBuffers {
3096 responder: BufferCollectionGetAuxBuffersResponder {
3097 control_handle: std::mem::ManuallyDrop::new(control_handle),
3098 tx_id: header.tx_id,
3099 },
3100 })
3101 }
3102 0x6f5adcca4ac7443e => {
3103 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
3104 let mut req = fidl::new_empty!(
3105 BufferCollectionAttachTokenRequest,
3106 fidl::encoding::DefaultFuchsiaResourceDialect
3107 );
3108 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachTokenRequest>(&header, _body_bytes, handles, &mut req)?;
3109 let control_handle =
3110 BufferCollectionControlHandle { inner: this.inner.clone() };
3111 Ok(BufferCollectionRequest::AttachToken {
3112 rights_attenuation_mask: req.rights_attenuation_mask,
3113 token_request: req.token_request,
3114
3115 control_handle,
3116 })
3117 }
3118 0x170d0f1d89d50989 => {
3119 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
3120 let mut req = fidl::new_empty!(
3121 BufferCollectionAttachLifetimeTrackingRequest,
3122 fidl::encoding::DefaultFuchsiaResourceDialect
3123 );
3124 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachLifetimeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
3125 let control_handle =
3126 BufferCollectionControlHandle { inner: this.inner.clone() };
3127 Ok(BufferCollectionRequest::AttachLifetimeTracking {
3128 server_end: req.server_end,
3129 buffers_remaining: req.buffers_remaining,
3130
3131 control_handle,
3132 })
3133 }
3134 _ => Err(fidl::Error::UnknownOrdinal {
3135 ordinal: header.ordinal,
3136 protocol_name:
3137 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
3138 }),
3139 }))
3140 },
3141 )
3142 }
3143}
3144
3145/// BufferCollection is a connection directly from a participant to sysmem re.
3146/// a logical BufferCollection; typically the logical BufferCollection is shared
3147/// with other participants. In other words, an instance of the BufferCollection
3148/// interface is a view of a "logical buffer collection".
3149///
3150/// This connection exists to facilitate async indication of when the logical
3151/// BufferCollection has been populated with buffers.
3152///
3153/// Also, the channel's closure by the server is an indication to the client
3154/// that the client should close all VMO handles that were obtained from the
3155/// BufferCollection ASAP.
3156///
3157/// Also, this interface may in future allow specifying constraints in other
3158/// ways, and may allow for back-and-forth negotiation of constraints to some
3159/// degree.
3160///
3161/// This interface may in future allow for more than 64 VMO handles per
3162/// BufferCollection, but currently the limit is 64.
3163///
3164/// This interface may in future allow for allocating/deallocating single
3165/// buffers.
3166///
3167/// Some initiators may wait a short duration until all old logical
3168/// BufferCollection VMO handles have closed (or until the short duration times
3169/// out) before allocating a new BufferCollection, to help control physical
3170/// memory fragmentation and avoid overlap of buffer allocation lifetimes for
3171/// the old and new collections. Collections can be large enough that it's worth
3172/// avoiding allocation overlap (in time).
3173#[derive(Debug)]
3174pub enum BufferCollectionRequest {
3175 /// Ensure that previous messages, including Duplicate() messages on a
3176 /// token, collection, or group, have been received server side.
3177 ///
3178 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
3179 /// valid sysmem token risks the Sync() hanging forever. See
3180 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
3181 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
3182 /// Another way is to pass the token to BindSharedCollection(), which also
3183 /// validates the token as part of exchanging it for a BufferCollection
3184 /// channel, and BufferCollection Sync() can then be used.
3185 ///
3186 /// After a Sync(), it's then safe to send the client end of token_request
3187 /// to another participant knowing the server will recognize the token when
3188 /// it's sent into BindSharedCollection() by the other participant.
3189 ///
3190 /// Other options include waiting for each token.Duplicate() to complete
3191 /// individually (using separate call to token.Sync() after each), or
3192 /// calling Sync() on BufferCollection after the token has been turned in
3193 /// via BindSharedCollection().
3194 ///
3195 /// Another way to mitigate is to avoid calling Sync() on the token, and
3196 /// instead later deal with potential failure of BufferCollection.Sync() if
3197 /// the original token was invalid. This option can be preferable from a
3198 /// performance point of view, but requires client code to delay sending
3199 /// tokens duplicated from this token until after client code has converted
3200 /// the duplicating token to a BufferCollection and received successful
3201 /// response from BufferCollection.Sync().
3202 ///
3203 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
3204 /// When BufferCollection.Sync() isn't feasible, the caller must already
3205 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
3206 /// hang forever. See ValidateBufferCollectionToken() to check token
3207 /// validity first if the token isn't already known to be (is/was) valid.
3208 Sync {
3209 responder: BufferCollectionSyncResponder,
3210 },
3211 /// On a BufferCollectionToken channel:
3212 ///
3213 /// Normally a participant will convert a BufferCollectionToken into a
3214 /// BufferCollection view, but a participant is also free to Close() the
3215 /// token (and then close the channel immediately or shortly later in
3216 /// response to server closing its end), which avoids causing logical buffer
3217 /// collection failure. Â Normally an unexpected token channel close will
3218 /// cause logical buffer collection failure (the only exceptions being
3219 /// certain cases involving AttachToken() or SetDispensable()).
3220 ///
3221 /// On a BufferCollection channel:
3222 ///
3223 /// By default the server handles unexpected failure of a BufferCollection
3224 /// by failing the whole logical buffer collection. Partly this is to
3225 /// expedite closing VMO handles to reclaim memory when any participant
3226 /// fails. If a participant would like to cleanly close a BufferCollection
3227 /// view without causing logical buffer collection failure, the participant
3228 /// can send Close() before closing the client end of the BufferCollection
3229 /// channel. If this is the last BufferCollection view, the logical buffer
3230 /// collection will still go away. The Close() can occur before or after
3231 /// SetConstraints(). If before SetConstraints(), the buffer collection
3232 /// won't require constraints from this node in order to allocate. If
3233 /// after SetConstraints(), the constraints are retained and aggregated
3234 /// along with any subsequent logical allocation(s), despite the lack of
3235 /// channel connection.
3236 ///
3237 /// On a BufferCollectionTokenGroup channel:
3238 ///
3239 /// By default, unexpected failure of a BufferCollectionTokenGroup will
3240 /// trigger failure of the logical BufferCollectionTokenGroup and will
3241 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
3242 /// channel without failing the logical group or propagating failure, send
3243 /// Close() before closing the channel client endpoint.
3244 ///
3245 /// If Close() occurs before AllChildrenPresent(), the logical buffer
3246 /// collection will still fail despite the Close() (because sysmem can't be
3247 /// sure whether all relevant children were created, so it's ambiguous
3248 /// whether all relevant constraints will be provided to sysmem). If
3249 /// Close() occurs after AllChildrenPresent(), the children and all their
3250 /// constraints remain intact (just as they would if the
3251 /// BufferCollectionTokenGroup channel had remained open), and the close
3252 /// doesn't trigger or propagate failure.
3253 Close {
3254 control_handle: BufferCollectionControlHandle,
3255 },
3256 /// Set a name for VMOs in this buffer collection. The name may be truncated
3257 /// shorter. The name only affects VMOs allocated after it's set - this call
3258 /// does not rename existing VMOs. If multiple clients set different names
3259 /// then the larger priority value will win.
3260 SetName {
3261 priority: u32,
3262 name: String,
3263 control_handle: BufferCollectionControlHandle,
3264 },
3265 /// Set information about the current client that can be used by sysmem to
3266 /// help debug leaking memory and hangs waiting for constraints. |name| can
3267 /// be an arbitrary string, but the current process name (see
3268 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
3269 /// arbitrary id, but the current process ID (see
3270 /// fsl::GetCurrentProcessKoid()) is a good default.
3271 ///
3272 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
3273 /// indicate which client is closing their channel first, leading to
3274 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
3275 /// over, but if happening earlier than expected, the
3276 /// client-channel-specific name can help diagnose where the failure is
3277 /// first coming from, from sysmem's point of view).
3278 ///
3279 /// By default (unless overriden by this message or using
3280 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
3281 /// parent Node at the time the child Node is created. While this can be
3282 /// better than nothing, it's often better for each participant to use
3283 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
3284 /// info directly relevant to the current client. Also, SetVerboseLogging()
3285 /// can be used to help disambiguate if a Node is suspected of having info
3286 /// that was copied from its parent.
3287 SetDebugClientInfo {
3288 name: String,
3289 id: u64,
3290 control_handle: BufferCollectionControlHandle,
3291 },
3292 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
3293 /// after creating a collection. Clients can call this method to change
3294 /// when the log is printed. If multiple client set the deadline, it's
3295 /// unspecified which deadline will take effect.
3296 SetDebugTimeoutLogDeadline {
3297 deadline: i64,
3298 control_handle: BufferCollectionControlHandle,
3299 },
3300 /// Verbose logging includes constraints set via SetConstraints() from each
3301 /// client along with info set via SetDebugClientInfo() and the structure of
3302 /// the tree of Node(s).
3303 ///
3304 /// Normally sysmem prints only a single line complaint when aggregation
3305 /// fails, with just the specific detailed reason that aggregation failed,
3306 /// with minimal context. While this is often enough to diagnose a problem
3307 /// if only a small change was made and the system had been working before
3308 /// the small change, it's often not particularly helpful for getting a new
3309 /// buffer collection to work for the first time. Especially with more
3310 /// complex trees of nodes, involving things like AttachToken(),
3311 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
3312 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
3313 /// looks like and why it's failing a logical allocation, or why a tree or
3314 /// sub-tree is failing sooner than expected.
3315 ///
3316 /// The intent of the extra logging is to be acceptable from a performance
3317 /// point of view, if only enabled on a low number of buffer collections.
3318 /// If we're not tracking down a bug, we shouldn't send this message.
3319 ///
3320 /// If too many participants leave verbose logging enabled, we may end up
3321 /// needing to require that system-wide sysmem verbose logging be permitted
3322 /// via some other setting, to avoid sysmem spamming the log too much due to
3323 /// this message.
3324 ///
3325 /// This may be a NOP for some nodes due to intentional policy associated
3326 /// with the node, if we don't trust a node enough to let it turn on verbose
3327 /// logging.
3328 SetVerboseLogging {
3329 control_handle: BufferCollectionControlHandle,
3330 },
3331 /// This gets an event handle that can be used as a parameter to
3332 /// IsAlternateFor() called on any Node. The client will not be granted the
3333 /// right to signal this event, as this handle should only be used as proof
3334 /// that the client obtained this handle from this Node.
3335 ///
3336 /// Because this is a get not a set, no Sync() is needed between the
3337 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
3338 /// potentially being on different channels.
3339 ///
3340 /// See also IsAlternateFor().
3341 GetNodeRef {
3342 responder: BufferCollectionGetNodeRefResponder,
3343 },
3344 /// This checks whether the calling node is in a subtree rooted at a
3345 /// different child token of a common parent BufferCollectionTokenGroup, in
3346 /// relation to the passed-in node_ref.
3347 ///
3348 /// This call is for assisting with admission control de-duplication, and
3349 /// with debugging.
3350 ///
3351 /// The node_ref must be obtained using GetNodeRef() of a
3352 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
3353 ///
3354 /// The node_ref can be a duplicated handle; it's not necessary to call
3355 /// GetNodeRef() for every call to IsAlternateFor().
3356 ///
3357 /// If a calling token may not actually be a valid token at all due to
3358 /// a potentially hostile/untrusted provider of the token, call
3359 /// ValidateBufferCollectionToken() first instead of potentially getting
3360 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
3361 /// token not being a real token (not really talking to sysmem). Another
3362 /// option is to call BindSharedCollection with this token first which also
3363 /// validates the token along with converting it to a BufferCollection, then
3364 /// call BufferCollection IsAlternateFor().
3365 ///
3366 /// error values:
3367 ///
3368 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
3369 /// buffer collection as the calling Node. Before logical allocation and
3370 /// within the same logical allocation sub-tree, this essentially means that
3371 /// the node_ref was never part of this logical buffer collection, since
3372 /// before logical allocation all node_refs that come into existence remain
3373 /// in existence at least until logical allocation (including Node(s) that
3374 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
3375 /// to be returned, this Node's channel needs to still be connected server
3376 /// side, which won't be the case if the whole logical allocation has
3377 /// failed. After logical allocation or in a different logical allocation
3378 /// sub-tree there are additional potential reasons for this error. For
3379 /// example a different logical allocation (separated from this Node(s)
3380 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
3381 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
3382 /// exist and may select a different child sub-tree than the sub-tree the
3383 /// node_ref is in causing deletion of the node_ref Node. The only time
3384 /// sysmem keeps a Node around after that Node has no corresponding channel
3385 /// is when Close() is used and the Node's sub-tree has not yet failed.
3386 /// Another reason for this error is if the node_ref is an eventpair handle
3387 /// with sufficient rights, but isn't actually a real node_ref obtained from
3388 /// GetNodeRef().
3389 ///
3390 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
3391 /// eventpair handle, or doesn't have the needed rights expected on a real
3392 /// node_ref.
3393 ///
3394 /// No other failing status codes are returned by this call. However,
3395 /// sysmem may add additional codes in future, so the client should have
3396 /// sensible default handling for any failing status code.
3397 ///
3398 /// On success, is_alternate has the following meaning:
3399 /// * true - The first parent node in common between the calling node and
3400 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
3401 /// the calling Node and the node_ref Node will _not_ have both their
3402 /// constraints apply - rather sysmem will choose one or the other of
3403 /// the constraints - never both. This is because only one child of
3404 /// a BufferCollectionTokenGroup is selected during logical allocation,
3405 /// with only that one child's sub-tree contributing to constraints
3406 /// aggregation.
3407 /// * false - The first parent node in common between the calling Node and
3408 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
3409 /// this means the first parent node in common is a
3410 /// BufferCollectionToken or BufferCollection (regardless of not
3411 /// Close()ed or Close()ed). This means that the calling Node and the
3412 /// node_ref Node _may_ have both their constraints apply during
3413 /// constraints aggregation of the logical allocation, if both Node(s)
3414 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
3415 /// In this case, there is no BufferCollectionTokenGroup that will
3416 /// directly prevent the two Node(s) from both being selected and their
3417 /// constraints both aggregated, but even when false, one or both
3418 /// Node(s) may still be eliminated from consideration if one or both
3419 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
3420 /// which selects a child sub-tree other than the sub-tree containing
3421 /// the calling Node or node_ref Node.
3422 IsAlternateFor {
3423 node_ref: fidl::Event,
3424 responder: BufferCollectionIsAlternateForResponder,
3425 },
3426 /// Provide BufferCollectionConstraints to the logical BufferCollection.
3427 ///
3428 /// A participant may only call SetConstraints() once.
3429 ///
3430 /// Sometimes the initiator is a participant only in the sense of wanting to
3431 /// keep an eye on success/failure to populate with buffers, and zx.Status
3432 /// on failure. In that case, `has_constraints` can be false, and
3433 /// `constraints` will be ignored.
3434 ///
3435 /// VMO handles will not be provided to the client that sends null
3436 /// constraints - that can be intentional for an initiator that doesn't need
3437 /// VMO handles. Not having VMO handles doesn't prevent the initator from
3438 /// adjusting which portion of a buffer is considered valid and similar, but
3439 /// the initiator can't hold a VMO handle open to prevent the logical
3440 /// BufferCollection from cleaning up if the logical BufferCollection needs
3441 /// to go away regardless of the initiator's degree of involvement for
3442 /// whatever reason.
3443 ///
3444 /// For population of buffers to be attempted, all holders of a
3445 /// BufferCollection client channel need to call SetConstraints() before
3446 /// sysmem will attempt to allocate buffers.
3447 ///
3448 /// `has_constraints` if false, the constraints are effectively null, and
3449 /// `constraints` are ignored. The sender of null constraints won't get any
3450 /// VMO handles in BufferCollectionInfo, but can still find out how many
3451 /// buffers were allocated and can still refer to buffers by their
3452 /// buffer_index.
3453 ///
3454 /// `constraints` are constraints on the buffer collection.
3455 SetConstraints {
3456 has_constraints: bool,
3457 constraints: BufferCollectionConstraints,
3458 control_handle: BufferCollectionControlHandle,
3459 },
3460 /// This request completes when buffers have been allocated, responds with
3461 /// some failure detail if allocation has been attempted but failed.
3462 ///
3463 /// The following must occur before buffers will be allocated:
3464 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
3465 /// must be turned in via BindSharedCollection().
3466 /// * All BufferCollection(s) of the logical BufferCollection must have
3467 /// had SetConstraints() sent to them.
3468 ///
3469 /// Returns `ZX_OK` if successful.
3470 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
3471 /// fulfilled due to resource exhaustion.
3472 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
3473 /// obtain the buffers it requested.
3474 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
3475 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
3476 /// satisfied, perhaps due to hardware limitations.
3477 ///
3478 /// `buffer_collection_info` has the VMO handles and other related info.
3479 WaitForBuffersAllocated {
3480 responder: BufferCollectionWaitForBuffersAllocatedResponder,
3481 },
3482 /// This returns the same result code as WaitForBuffersAllocated if the
3483 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
3484 /// if WaitForBuffersAllocated would block.
3485 CheckBuffersAllocated {
3486 responder: BufferCollectionCheckBuffersAllocatedResponder,
3487 },
3488 SetConstraintsAuxBuffers {
3489 constraints: BufferCollectionConstraintsAuxBuffers,
3490 control_handle: BufferCollectionControlHandle,
3491 },
3492 GetAuxBuffers {
3493 responder: BufferCollectionGetAuxBuffersResponder,
3494 },
3495 /// Create a new token, for trying to add a new participant to an existing
3496 /// collection, if the existing collection's buffer counts, constraints,
3497 /// and participants allow.
3498 ///
3499 /// This can be useful in replacing a failed participant, and/or in
3500 /// adding/re-adding a participant after buffers have already been
3501 /// allocated.
3502 ///
3503 /// Failure of an attached token / collection does not propagate to the
3504 /// parent of the attached token. Failure does propagate from a normal
3505 /// child of a dispensable token to the dispensable token. Failure
3506 /// of a child is blocked from reaching its parent if the child is attached,
3507 /// or if the child is dispensable and the failure occurred after logical
3508 /// allocation.
3509 ///
3510 /// An initiator may in some scenarios choose to initially use a dispensable
3511 /// token for a given instance of a participant, and then later if the first
3512 /// instance of that participant fails, a new second instance of that
3513 /// participant my be given a token created with AttachToken().
3514 ///
3515 /// From the point of view of the client end of the BufferCollectionToken
3516 /// channel, the token acts like any other token. The client can
3517 /// Duplicate() the token as needed, and can send the token to a different
3518 /// process. The token should be converted to a BufferCollection channel
3519 /// as normal by calling BindSharedCollection(). SetConstraints() should
3520 /// be called on that BufferCollection channel.
3521 ///
3522 /// A success result from WaitForBuffersAllocated() means the new
3523 /// participant's constraints were satisfiable using the already-existing
3524 /// buffer collection, the already-established BufferCollectionInfo
3525 /// including image format constraints, and the already-existing other
3526 /// participants and their buffer counts. A failure result means the new
3527 /// participant's constraints cannot be satisfied using the existing
3528 /// buffer collection and its already-logically-allocated participants.
3529 /// Creating a new collection instead may allow all participant's
3530 /// constraints to be satisfied, assuming SetDispensable() is used in place
3531 /// of AttachToken(), or a normal token is used.
3532 ///
3533 /// A token created with AttachToken() performs constraints aggregation with
3534 /// all constraints currently in effect on the buffer collection, plus the
3535 /// attached token under consideration plus child tokens under the attached
3536 /// token which are not themselves an attached token or under such a token.
3537 ///
3538 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
3539 /// first-come first-served, but a child can't logically allocate before
3540 /// all its parents have sent SetConstraints().
3541 ///
3542 /// See also SetDispensable(), which in contrast to AttachToken(), has the
3543 /// created token + children participate in constraints aggregation along
3544 /// with its parent.
3545 ///
3546 /// The newly created token needs to be Sync()ed to sysmem before the new
3547 /// token can be passed to BindSharedCollection(). The Sync() of the new
3548 /// token can be accomplished with BufferCollection.Sync() on this
3549 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
3550 /// token also works. A BufferCollectionToken.Sync() can be started after
3551 /// any BufferCollectionToken.Duplicate() messages have been sent via the
3552 /// newly created token, to also sync those additional tokens to sysmem
3553 /// using a single round-trip.
3554 ///
3555 /// These values for rights_attenuation_mask result in no attenuation (note
3556 /// that 0 is not on this list; 0 will output an ERROR to the system log
3557 /// to help diagnose the bug in client code):
3558 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
3559 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
3560 AttachToken {
3561 rights_attenuation_mask: u32,
3562 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
3563 control_handle: BufferCollectionControlHandle,
3564 },
3565 /// AttachLifetimeTracking:
3566 ///
3567 /// AttachLifetimeTracking() is intended to allow a client to wait until an
3568 /// old logical buffer collection is fully or mostly deallocated before
3569 /// attempting allocation of a new logical buffer collection.
3570 ///
3571 /// Attach an eventpair endpoint to the logical buffer collection, so that
3572 /// the server_end will be closed when the number of buffers allocated
3573 /// drops to 'buffers_remaining'. The server_end won't close until after
3574 /// logical allocation has completed.
3575 ///
3576 /// If logical allocation fails, such as for an attached sub-tree (using
3577 /// AttachToken()), the server_end will close during that failure regardless
3578 /// of the number of buffers potenitally allocated in the overall logical
3579 /// buffer collection.
3580 ///
3581 /// The lifetime signalled by this event includes asynchronous cleanup of
3582 /// allocated buffers, and this asynchronous cleanup cannot occur until all
3583 /// holders of VMO handles to the buffers have closed those VMO handles.
3584 /// Therefore clients should take care not to become blocked forever waiting
3585 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
3586 /// participants using the logical buffer collection are less trusted or
3587 /// less reliable.
3588 ///
3589 /// The buffers_remaining parameter allows waiting for all but
3590 /// buffers_remaining buffers to be fully deallocated. This can be useful
3591 /// in situations where a known number of buffers are intentionally not
3592 /// closed so that the data can continue to be used, such as for keeping the
3593 /// last available video picture displayed in the UI even if the video
3594 /// stream was using protected output buffers. It's outside the scope of
3595 /// the BufferCollection interface (at least for now) to determine how many
3596 /// buffers may be held without closing, but it'll typically be in the range
3597 /// 0-2.
3598 ///
3599 /// This mechanism is meant to be compatible with other protocols providing
3600 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
3601 /// same event can be sent to more than one AttachLifetimeTracking(), and
3602 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
3603 /// over conditions are met (all holders of duplicates have closed their
3604 /// handle(s)).
3605 ///
3606 /// There is no way to cancel an attach. Closing the client end of the
3607 /// eventpair doesn't subtract from the number of pending attach(es).
3608 ///
3609 /// Closing the client's end doesn't result in any action by the server.
3610 /// If the server listens to events from the client end at all, it is for
3611 /// debug logging only.
3612 ///
3613 /// The server intentionally doesn't "trust" any bits signalled by the
3614 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
3615 /// which can't be triggered early, and is only triggered when all handles
3616 /// to server_end are closed. No meaning is associated with any of the
3617 /// other signal bits, and clients should functionally ignore any other
3618 /// signal bits on either end of the eventpair or its peer.
3619 ///
3620 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
3621 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
3622 /// transfer without causing CodecFactory channel failure).
3623 AttachLifetimeTracking {
3624 server_end: fidl::EventPair,
3625 buffers_remaining: u32,
3626 control_handle: BufferCollectionControlHandle,
3627 },
3628}
3629
3630impl BufferCollectionRequest {
3631 #[allow(irrefutable_let_patterns)]
3632 pub fn into_sync(self) -> Option<(BufferCollectionSyncResponder)> {
3633 if let BufferCollectionRequest::Sync { responder } = self {
3634 Some((responder))
3635 } else {
3636 None
3637 }
3638 }
3639
3640 #[allow(irrefutable_let_patterns)]
3641 pub fn into_close(self) -> Option<(BufferCollectionControlHandle)> {
3642 if let BufferCollectionRequest::Close { control_handle } = self {
3643 Some((control_handle))
3644 } else {
3645 None
3646 }
3647 }
3648
3649 #[allow(irrefutable_let_patterns)]
3650 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionControlHandle)> {
3651 if let BufferCollectionRequest::SetName { priority, name, control_handle } = self {
3652 Some((priority, name, control_handle))
3653 } else {
3654 None
3655 }
3656 }
3657
3658 #[allow(irrefutable_let_patterns)]
3659 pub fn into_set_debug_client_info(
3660 self,
3661 ) -> Option<(String, u64, BufferCollectionControlHandle)> {
3662 if let BufferCollectionRequest::SetDebugClientInfo { name, id, control_handle } = self {
3663 Some((name, id, control_handle))
3664 } else {
3665 None
3666 }
3667 }
3668
3669 #[allow(irrefutable_let_patterns)]
3670 pub fn into_set_debug_timeout_log_deadline(
3671 self,
3672 ) -> Option<(i64, BufferCollectionControlHandle)> {
3673 if let BufferCollectionRequest::SetDebugTimeoutLogDeadline { deadline, control_handle } =
3674 self
3675 {
3676 Some((deadline, control_handle))
3677 } else {
3678 None
3679 }
3680 }
3681
3682 #[allow(irrefutable_let_patterns)]
3683 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionControlHandle)> {
3684 if let BufferCollectionRequest::SetVerboseLogging { control_handle } = self {
3685 Some((control_handle))
3686 } else {
3687 None
3688 }
3689 }
3690
3691 #[allow(irrefutable_let_patterns)]
3692 pub fn into_get_node_ref(self) -> Option<(BufferCollectionGetNodeRefResponder)> {
3693 if let BufferCollectionRequest::GetNodeRef { responder } = self {
3694 Some((responder))
3695 } else {
3696 None
3697 }
3698 }
3699
3700 #[allow(irrefutable_let_patterns)]
3701 pub fn into_is_alternate_for(
3702 self,
3703 ) -> Option<(fidl::Event, BufferCollectionIsAlternateForResponder)> {
3704 if let BufferCollectionRequest::IsAlternateFor { node_ref, responder } = self {
3705 Some((node_ref, responder))
3706 } else {
3707 None
3708 }
3709 }
3710
3711 #[allow(irrefutable_let_patterns)]
3712 pub fn into_set_constraints(
3713 self,
3714 ) -> Option<(bool, BufferCollectionConstraints, BufferCollectionControlHandle)> {
3715 if let BufferCollectionRequest::SetConstraints {
3716 has_constraints,
3717 constraints,
3718 control_handle,
3719 } = self
3720 {
3721 Some((has_constraints, constraints, control_handle))
3722 } else {
3723 None
3724 }
3725 }
3726
3727 #[allow(irrefutable_let_patterns)]
3728 pub fn into_wait_for_buffers_allocated(
3729 self,
3730 ) -> Option<(BufferCollectionWaitForBuffersAllocatedResponder)> {
3731 if let BufferCollectionRequest::WaitForBuffersAllocated { responder } = self {
3732 Some((responder))
3733 } else {
3734 None
3735 }
3736 }
3737
3738 #[allow(irrefutable_let_patterns)]
3739 pub fn into_check_buffers_allocated(
3740 self,
3741 ) -> Option<(BufferCollectionCheckBuffersAllocatedResponder)> {
3742 if let BufferCollectionRequest::CheckBuffersAllocated { responder } = self {
3743 Some((responder))
3744 } else {
3745 None
3746 }
3747 }
3748
3749 #[allow(irrefutable_let_patterns)]
3750 pub fn into_set_constraints_aux_buffers(
3751 self,
3752 ) -> Option<(BufferCollectionConstraintsAuxBuffers, BufferCollectionControlHandle)> {
3753 if let BufferCollectionRequest::SetConstraintsAuxBuffers { constraints, control_handle } =
3754 self
3755 {
3756 Some((constraints, control_handle))
3757 } else {
3758 None
3759 }
3760 }
3761
3762 #[allow(irrefutable_let_patterns)]
3763 pub fn into_get_aux_buffers(self) -> Option<(BufferCollectionGetAuxBuffersResponder)> {
3764 if let BufferCollectionRequest::GetAuxBuffers { responder } = self {
3765 Some((responder))
3766 } else {
3767 None
3768 }
3769 }
3770
3771 #[allow(irrefutable_let_patterns)]
3772 pub fn into_attach_token(
3773 self,
3774 ) -> Option<(
3775 u32,
3776 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
3777 BufferCollectionControlHandle,
3778 )> {
3779 if let BufferCollectionRequest::AttachToken {
3780 rights_attenuation_mask,
3781 token_request,
3782 control_handle,
3783 } = self
3784 {
3785 Some((rights_attenuation_mask, token_request, control_handle))
3786 } else {
3787 None
3788 }
3789 }
3790
3791 #[allow(irrefutable_let_patterns)]
3792 pub fn into_attach_lifetime_tracking(
3793 self,
3794 ) -> Option<(fidl::EventPair, u32, BufferCollectionControlHandle)> {
3795 if let BufferCollectionRequest::AttachLifetimeTracking {
3796 server_end,
3797 buffers_remaining,
3798 control_handle,
3799 } = self
3800 {
3801 Some((server_end, buffers_remaining, control_handle))
3802 } else {
3803 None
3804 }
3805 }
3806
3807 /// Name of the method defined in FIDL
3808 pub fn method_name(&self) -> &'static str {
3809 match *self {
3810 BufferCollectionRequest::Sync { .. } => "sync",
3811 BufferCollectionRequest::Close { .. } => "close",
3812 BufferCollectionRequest::SetName { .. } => "set_name",
3813 BufferCollectionRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
3814 BufferCollectionRequest::SetDebugTimeoutLogDeadline { .. } => {
3815 "set_debug_timeout_log_deadline"
3816 }
3817 BufferCollectionRequest::SetVerboseLogging { .. } => "set_verbose_logging",
3818 BufferCollectionRequest::GetNodeRef { .. } => "get_node_ref",
3819 BufferCollectionRequest::IsAlternateFor { .. } => "is_alternate_for",
3820 BufferCollectionRequest::SetConstraints { .. } => "set_constraints",
3821 BufferCollectionRequest::WaitForBuffersAllocated { .. } => "wait_for_buffers_allocated",
3822 BufferCollectionRequest::CheckBuffersAllocated { .. } => "check_buffers_allocated",
3823 BufferCollectionRequest::SetConstraintsAuxBuffers { .. } => {
3824 "set_constraints_aux_buffers"
3825 }
3826 BufferCollectionRequest::GetAuxBuffers { .. } => "get_aux_buffers",
3827 BufferCollectionRequest::AttachToken { .. } => "attach_token",
3828 BufferCollectionRequest::AttachLifetimeTracking { .. } => "attach_lifetime_tracking",
3829 }
3830 }
3831}
3832
3833#[derive(Debug, Clone)]
3834pub struct BufferCollectionControlHandle {
3835 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
3836}
3837
3838impl fidl::endpoints::ControlHandle for BufferCollectionControlHandle {
3839 fn shutdown(&self) {
3840 self.inner.shutdown()
3841 }
3842 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
3843 self.inner.shutdown_with_epitaph(status)
3844 }
3845
3846 fn is_closed(&self) -> bool {
3847 self.inner.channel().is_closed()
3848 }
3849 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
3850 self.inner.channel().on_closed()
3851 }
3852
3853 #[cfg(target_os = "fuchsia")]
3854 fn signal_peer(
3855 &self,
3856 clear_mask: zx::Signals,
3857 set_mask: zx::Signals,
3858 ) -> Result<(), zx_status::Status> {
3859 use fidl::Peered;
3860 self.inner.channel().signal_peer(clear_mask, set_mask)
3861 }
3862}
3863
3864impl BufferCollectionControlHandle {}
3865
3866#[must_use = "FIDL methods require a response to be sent"]
3867#[derive(Debug)]
3868pub struct BufferCollectionSyncResponder {
3869 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3870 tx_id: u32,
3871}
3872
3873/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3874/// if the responder is dropped without sending a response, so that the client
3875/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3876impl std::ops::Drop for BufferCollectionSyncResponder {
3877 fn drop(&mut self) {
3878 self.control_handle.shutdown();
3879 // Safety: drops once, never accessed again
3880 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3881 }
3882}
3883
3884impl fidl::endpoints::Responder for BufferCollectionSyncResponder {
3885 type ControlHandle = BufferCollectionControlHandle;
3886
3887 fn control_handle(&self) -> &BufferCollectionControlHandle {
3888 &self.control_handle
3889 }
3890
3891 fn drop_without_shutdown(mut self) {
3892 // Safety: drops once, never accessed again due to mem::forget
3893 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3894 // Prevent Drop from running (which would shut down the channel)
3895 std::mem::forget(self);
3896 }
3897}
3898
3899impl BufferCollectionSyncResponder {
3900 /// Sends a response to the FIDL transaction.
3901 ///
3902 /// Sets the channel to shutdown if an error occurs.
3903 pub fn send(self) -> Result<(), fidl::Error> {
3904 let _result = self.send_raw();
3905 if _result.is_err() {
3906 self.control_handle.shutdown();
3907 }
3908 self.drop_without_shutdown();
3909 _result
3910 }
3911
3912 /// Similar to "send" but does not shutdown the channel if an error occurs.
3913 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
3914 let _result = self.send_raw();
3915 self.drop_without_shutdown();
3916 _result
3917 }
3918
3919 fn send_raw(&self) -> Result<(), fidl::Error> {
3920 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
3921 (),
3922 self.tx_id,
3923 0x4577e238ae26291,
3924 fidl::encoding::DynamicFlags::empty(),
3925 )
3926 }
3927}
3928
3929#[must_use = "FIDL methods require a response to be sent"]
3930#[derive(Debug)]
3931pub struct BufferCollectionGetNodeRefResponder {
3932 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3933 tx_id: u32,
3934}
3935
3936/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3937/// if the responder is dropped without sending a response, so that the client
3938/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3939impl std::ops::Drop for BufferCollectionGetNodeRefResponder {
3940 fn drop(&mut self) {
3941 self.control_handle.shutdown();
3942 // Safety: drops once, never accessed again
3943 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3944 }
3945}
3946
3947impl fidl::endpoints::Responder for BufferCollectionGetNodeRefResponder {
3948 type ControlHandle = BufferCollectionControlHandle;
3949
3950 fn control_handle(&self) -> &BufferCollectionControlHandle {
3951 &self.control_handle
3952 }
3953
3954 fn drop_without_shutdown(mut self) {
3955 // Safety: drops once, never accessed again due to mem::forget
3956 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3957 // Prevent Drop from running (which would shut down the channel)
3958 std::mem::forget(self);
3959 }
3960}
3961
3962impl BufferCollectionGetNodeRefResponder {
3963 /// Sends a response to the FIDL transaction.
3964 ///
3965 /// Sets the channel to shutdown if an error occurs.
3966 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3967 let _result = self.send_raw(node_ref);
3968 if _result.is_err() {
3969 self.control_handle.shutdown();
3970 }
3971 self.drop_without_shutdown();
3972 _result
3973 }
3974
3975 /// Similar to "send" but does not shutdown the channel if an error occurs.
3976 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3977 let _result = self.send_raw(node_ref);
3978 self.drop_without_shutdown();
3979 _result
3980 }
3981
3982 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3983 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
3984 (node_ref,),
3985 self.tx_id,
3986 0x467b7c75c35c3b84,
3987 fidl::encoding::DynamicFlags::empty(),
3988 )
3989 }
3990}
3991
3992#[must_use = "FIDL methods require a response to be sent"]
3993#[derive(Debug)]
3994pub struct BufferCollectionIsAlternateForResponder {
3995 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3996 tx_id: u32,
3997}
3998
3999/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
4000/// if the responder is dropped without sending a response, so that the client
4001/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
4002impl std::ops::Drop for BufferCollectionIsAlternateForResponder {
4003 fn drop(&mut self) {
4004 self.control_handle.shutdown();
4005 // Safety: drops once, never accessed again
4006 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4007 }
4008}
4009
4010impl fidl::endpoints::Responder for BufferCollectionIsAlternateForResponder {
4011 type ControlHandle = BufferCollectionControlHandle;
4012
4013 fn control_handle(&self) -> &BufferCollectionControlHandle {
4014 &self.control_handle
4015 }
4016
4017 fn drop_without_shutdown(mut self) {
4018 // Safety: drops once, never accessed again due to mem::forget
4019 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4020 // Prevent Drop from running (which would shut down the channel)
4021 std::mem::forget(self);
4022 }
4023}
4024
4025impl BufferCollectionIsAlternateForResponder {
4026 /// Sends a response to the FIDL transaction.
4027 ///
4028 /// Sets the channel to shutdown if an error occurs.
4029 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
4030 let _result = self.send_raw(result);
4031 if _result.is_err() {
4032 self.control_handle.shutdown();
4033 }
4034 self.drop_without_shutdown();
4035 _result
4036 }
4037
4038 /// Similar to "send" but does not shutdown the channel if an error occurs.
4039 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
4040 let _result = self.send_raw(result);
4041 self.drop_without_shutdown();
4042 _result
4043 }
4044
4045 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
4046 self.control_handle
4047 .inner
4048 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
4049 result.map(|is_alternate| (is_alternate,)),
4050 self.tx_id,
4051 0x33a2a7aff2776c07,
4052 fidl::encoding::DynamicFlags::empty(),
4053 )
4054 }
4055}
4056
4057#[must_use = "FIDL methods require a response to be sent"]
4058#[derive(Debug)]
4059pub struct BufferCollectionWaitForBuffersAllocatedResponder {
4060 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
4061 tx_id: u32,
4062}
4063
4064/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
4065/// if the responder is dropped without sending a response, so that the client
4066/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
4067impl std::ops::Drop for BufferCollectionWaitForBuffersAllocatedResponder {
4068 fn drop(&mut self) {
4069 self.control_handle.shutdown();
4070 // Safety: drops once, never accessed again
4071 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4072 }
4073}
4074
4075impl fidl::endpoints::Responder for BufferCollectionWaitForBuffersAllocatedResponder {
4076 type ControlHandle = BufferCollectionControlHandle;
4077
4078 fn control_handle(&self) -> &BufferCollectionControlHandle {
4079 &self.control_handle
4080 }
4081
4082 fn drop_without_shutdown(mut self) {
4083 // Safety: drops once, never accessed again due to mem::forget
4084 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4085 // Prevent Drop from running (which would shut down the channel)
4086 std::mem::forget(self);
4087 }
4088}
4089
4090impl BufferCollectionWaitForBuffersAllocatedResponder {
4091 /// Sends a response to the FIDL transaction.
4092 ///
4093 /// Sets the channel to shutdown if an error occurs.
4094 pub fn send(
4095 self,
4096 mut status: i32,
4097 mut buffer_collection_info: BufferCollectionInfo2,
4098 ) -> Result<(), fidl::Error> {
4099 let _result = self.send_raw(status, buffer_collection_info);
4100 if _result.is_err() {
4101 self.control_handle.shutdown();
4102 }
4103 self.drop_without_shutdown();
4104 _result
4105 }
4106
4107 /// Similar to "send" but does not shutdown the channel if an error occurs.
4108 pub fn send_no_shutdown_on_err(
4109 self,
4110 mut status: i32,
4111 mut buffer_collection_info: BufferCollectionInfo2,
4112 ) -> Result<(), fidl::Error> {
4113 let _result = self.send_raw(status, buffer_collection_info);
4114 self.drop_without_shutdown();
4115 _result
4116 }
4117
4118 fn send_raw(
4119 &self,
4120 mut status: i32,
4121 mut buffer_collection_info: BufferCollectionInfo2,
4122 ) -> Result<(), fidl::Error> {
4123 self.control_handle.inner.send::<BufferCollectionWaitForBuffersAllocatedResponse>(
4124 (status, &mut buffer_collection_info),
4125 self.tx_id,
4126 0x714667ea2a29a3a2,
4127 fidl::encoding::DynamicFlags::empty(),
4128 )
4129 }
4130}
4131
4132#[must_use = "FIDL methods require a response to be sent"]
4133#[derive(Debug)]
4134pub struct BufferCollectionCheckBuffersAllocatedResponder {
4135 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
4136 tx_id: u32,
4137}
4138
4139/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
4140/// if the responder is dropped without sending a response, so that the client
4141/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
4142impl std::ops::Drop for BufferCollectionCheckBuffersAllocatedResponder {
4143 fn drop(&mut self) {
4144 self.control_handle.shutdown();
4145 // Safety: drops once, never accessed again
4146 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4147 }
4148}
4149
4150impl fidl::endpoints::Responder for BufferCollectionCheckBuffersAllocatedResponder {
4151 type ControlHandle = BufferCollectionControlHandle;
4152
4153 fn control_handle(&self) -> &BufferCollectionControlHandle {
4154 &self.control_handle
4155 }
4156
4157 fn drop_without_shutdown(mut self) {
4158 // Safety: drops once, never accessed again due to mem::forget
4159 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4160 // Prevent Drop from running (which would shut down the channel)
4161 std::mem::forget(self);
4162 }
4163}
4164
4165impl BufferCollectionCheckBuffersAllocatedResponder {
4166 /// Sends a response to the FIDL transaction.
4167 ///
4168 /// Sets the channel to shutdown if an error occurs.
4169 pub fn send(self, mut status: i32) -> Result<(), fidl::Error> {
4170 let _result = self.send_raw(status);
4171 if _result.is_err() {
4172 self.control_handle.shutdown();
4173 }
4174 self.drop_without_shutdown();
4175 _result
4176 }
4177
4178 /// Similar to "send" but does not shutdown the channel if an error occurs.
4179 pub fn send_no_shutdown_on_err(self, mut status: i32) -> Result<(), fidl::Error> {
4180 let _result = self.send_raw(status);
4181 self.drop_without_shutdown();
4182 _result
4183 }
4184
4185 fn send_raw(&self, mut status: i32) -> Result<(), fidl::Error> {
4186 self.control_handle.inner.send::<BufferCollectionCheckBuffersAllocatedResponse>(
4187 (status,),
4188 self.tx_id,
4189 0x245bb81f79189e9,
4190 fidl::encoding::DynamicFlags::empty(),
4191 )
4192 }
4193}
4194
4195#[must_use = "FIDL methods require a response to be sent"]
4196#[derive(Debug)]
4197pub struct BufferCollectionGetAuxBuffersResponder {
4198 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
4199 tx_id: u32,
4200}
4201
4202/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
4203/// if the responder is dropped without sending a response, so that the client
4204/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
4205impl std::ops::Drop for BufferCollectionGetAuxBuffersResponder {
4206 fn drop(&mut self) {
4207 self.control_handle.shutdown();
4208 // Safety: drops once, never accessed again
4209 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4210 }
4211}
4212
4213impl fidl::endpoints::Responder for BufferCollectionGetAuxBuffersResponder {
4214 type ControlHandle = BufferCollectionControlHandle;
4215
4216 fn control_handle(&self) -> &BufferCollectionControlHandle {
4217 &self.control_handle
4218 }
4219
4220 fn drop_without_shutdown(mut self) {
4221 // Safety: drops once, never accessed again due to mem::forget
4222 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4223 // Prevent Drop from running (which would shut down the channel)
4224 std::mem::forget(self);
4225 }
4226}
4227
4228impl BufferCollectionGetAuxBuffersResponder {
4229 /// Sends a response to the FIDL transaction.
4230 ///
4231 /// Sets the channel to shutdown if an error occurs.
4232 pub fn send(
4233 self,
4234 mut status: i32,
4235 mut buffer_collection_info_aux_buffers: BufferCollectionInfo2,
4236 ) -> Result<(), fidl::Error> {
4237 let _result = self.send_raw(status, buffer_collection_info_aux_buffers);
4238 if _result.is_err() {
4239 self.control_handle.shutdown();
4240 }
4241 self.drop_without_shutdown();
4242 _result
4243 }
4244
4245 /// Similar to "send" but does not shutdown the channel if an error occurs.
4246 pub fn send_no_shutdown_on_err(
4247 self,
4248 mut status: i32,
4249 mut buffer_collection_info_aux_buffers: BufferCollectionInfo2,
4250 ) -> Result<(), fidl::Error> {
4251 let _result = self.send_raw(status, buffer_collection_info_aux_buffers);
4252 self.drop_without_shutdown();
4253 _result
4254 }
4255
4256 fn send_raw(
4257 &self,
4258 mut status: i32,
4259 mut buffer_collection_info_aux_buffers: BufferCollectionInfo2,
4260 ) -> Result<(), fidl::Error> {
4261 self.control_handle.inner.send::<BufferCollectionGetAuxBuffersResponse>(
4262 (status, &mut buffer_collection_info_aux_buffers),
4263 self.tx_id,
4264 0x6c6cac6000a29a55,
4265 fidl::encoding::DynamicFlags::empty(),
4266 )
4267 }
4268}
4269
4270#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
4271pub struct BufferCollectionTokenMarker;
4272
4273impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenMarker {
4274 type Proxy = BufferCollectionTokenProxy;
4275 type RequestStream = BufferCollectionTokenRequestStream;
4276 #[cfg(target_os = "fuchsia")]
4277 type SynchronousProxy = BufferCollectionTokenSynchronousProxy;
4278
4279 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionToken";
4280}
4281
4282pub trait BufferCollectionTokenProxyInterface: Send + Sync {
4283 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
4284 fn r#sync(&self) -> Self::SyncResponseFut;
4285 fn r#close(&self) -> Result<(), fidl::Error>;
4286 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
4287 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
4288 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
4289 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
4290 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
4291 + Send;
4292 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
4293 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
4294 + Send;
4295 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
4296 type DuplicateSyncResponseFut: std::future::Future<
4297 Output = Result<
4298 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
4299 fidl::Error,
4300 >,
4301 > + Send;
4302 fn r#duplicate_sync(
4303 &self,
4304 rights_attenuation_masks: &[fidl::Rights],
4305 ) -> Self::DuplicateSyncResponseFut;
4306 fn r#duplicate(
4307 &self,
4308 rights_attenuation_mask: u32,
4309 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
4310 ) -> Result<(), fidl::Error>;
4311 fn r#set_dispensable(&self) -> Result<(), fidl::Error>;
4312 fn r#create_buffer_collection_token_group(
4313 &self,
4314 group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
4315 ) -> Result<(), fidl::Error>;
4316}
4317#[derive(Debug)]
4318#[cfg(target_os = "fuchsia")]
4319pub struct BufferCollectionTokenSynchronousProxy {
4320 client: fidl::client::sync::Client,
4321}
4322
4323#[cfg(target_os = "fuchsia")]
4324impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenSynchronousProxy {
4325 type Proxy = BufferCollectionTokenProxy;
4326 type Protocol = BufferCollectionTokenMarker;
4327
4328 fn from_channel(inner: fidl::Channel) -> Self {
4329 Self::new(inner)
4330 }
4331
4332 fn into_channel(self) -> fidl::Channel {
4333 self.client.into_channel()
4334 }
4335
4336 fn as_channel(&self) -> &fidl::Channel {
4337 self.client.as_channel()
4338 }
4339}
4340
4341#[cfg(target_os = "fuchsia")]
4342impl BufferCollectionTokenSynchronousProxy {
4343 pub fn new(channel: fidl::Channel) -> Self {
4344 let protocol_name =
4345 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
4346 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
4347 }
4348
4349 pub fn into_channel(self) -> fidl::Channel {
4350 self.client.into_channel()
4351 }
4352
4353 /// Waits until an event arrives and returns it. It is safe for other
4354 /// threads to make concurrent requests while waiting for an event.
4355 pub fn wait_for_event(
4356 &self,
4357 deadline: zx::MonotonicInstant,
4358 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
4359 BufferCollectionTokenEvent::decode(self.client.wait_for_event(deadline)?)
4360 }
4361
4362 /// Ensure that previous messages, including Duplicate() messages on a
4363 /// token, collection, or group, have been received server side.
4364 ///
4365 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
4366 /// valid sysmem token risks the Sync() hanging forever. See
4367 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
4368 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
4369 /// Another way is to pass the token to BindSharedCollection(), which also
4370 /// validates the token as part of exchanging it for a BufferCollection
4371 /// channel, and BufferCollection Sync() can then be used.
4372 ///
4373 /// After a Sync(), it's then safe to send the client end of token_request
4374 /// to another participant knowing the server will recognize the token when
4375 /// it's sent into BindSharedCollection() by the other participant.
4376 ///
4377 /// Other options include waiting for each token.Duplicate() to complete
4378 /// individually (using separate call to token.Sync() after each), or
4379 /// calling Sync() on BufferCollection after the token has been turned in
4380 /// via BindSharedCollection().
4381 ///
4382 /// Another way to mitigate is to avoid calling Sync() on the token, and
4383 /// instead later deal with potential failure of BufferCollection.Sync() if
4384 /// the original token was invalid. This option can be preferable from a
4385 /// performance point of view, but requires client code to delay sending
4386 /// tokens duplicated from this token until after client code has converted
4387 /// the duplicating token to a BufferCollection and received successful
4388 /// response from BufferCollection.Sync().
4389 ///
4390 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
4391 /// When BufferCollection.Sync() isn't feasible, the caller must already
4392 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
4393 /// hang forever. See ValidateBufferCollectionToken() to check token
4394 /// validity first if the token isn't already known to be (is/was) valid.
4395 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
4396 let _response =
4397 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
4398 (),
4399 0x4577e238ae26291,
4400 fidl::encoding::DynamicFlags::empty(),
4401 ___deadline,
4402 )?;
4403 Ok(_response)
4404 }
4405
4406 /// On a BufferCollectionToken channel:
4407 ///
4408 /// Normally a participant will convert a BufferCollectionToken into a
4409 /// BufferCollection view, but a participant is also free to Close() the
4410 /// token (and then close the channel immediately or shortly later in
4411 /// response to server closing its end), which avoids causing logical buffer
4412 /// collection failure. Â Normally an unexpected token channel close will
4413 /// cause logical buffer collection failure (the only exceptions being
4414 /// certain cases involving AttachToken() or SetDispensable()).
4415 ///
4416 /// On a BufferCollection channel:
4417 ///
4418 /// By default the server handles unexpected failure of a BufferCollection
4419 /// by failing the whole logical buffer collection. Partly this is to
4420 /// expedite closing VMO handles to reclaim memory when any participant
4421 /// fails. If a participant would like to cleanly close a BufferCollection
4422 /// view without causing logical buffer collection failure, the participant
4423 /// can send Close() before closing the client end of the BufferCollection
4424 /// channel. If this is the last BufferCollection view, the logical buffer
4425 /// collection will still go away. The Close() can occur before or after
4426 /// SetConstraints(). If before SetConstraints(), the buffer collection
4427 /// won't require constraints from this node in order to allocate. If
4428 /// after SetConstraints(), the constraints are retained and aggregated
4429 /// along with any subsequent logical allocation(s), despite the lack of
4430 /// channel connection.
4431 ///
4432 /// On a BufferCollectionTokenGroup channel:
4433 ///
4434 /// By default, unexpected failure of a BufferCollectionTokenGroup will
4435 /// trigger failure of the logical BufferCollectionTokenGroup and will
4436 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
4437 /// channel without failing the logical group or propagating failure, send
4438 /// Close() before closing the channel client endpoint.
4439 ///
4440 /// If Close() occurs before AllChildrenPresent(), the logical buffer
4441 /// collection will still fail despite the Close() (because sysmem can't be
4442 /// sure whether all relevant children were created, so it's ambiguous
4443 /// whether all relevant constraints will be provided to sysmem). If
4444 /// Close() occurs after AllChildrenPresent(), the children and all their
4445 /// constraints remain intact (just as they would if the
4446 /// BufferCollectionTokenGroup channel had remained open), and the close
4447 /// doesn't trigger or propagate failure.
4448 pub fn r#close(&self) -> Result<(), fidl::Error> {
4449 self.client.send::<fidl::encoding::EmptyPayload>(
4450 (),
4451 0x5b1d7a4f5681fca7,
4452 fidl::encoding::DynamicFlags::empty(),
4453 )
4454 }
4455
4456 /// Set a name for VMOs in this buffer collection. The name may be truncated
4457 /// shorter. The name only affects VMOs allocated after it's set - this call
4458 /// does not rename existing VMOs. If multiple clients set different names
4459 /// then the larger priority value will win.
4460 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
4461 self.client.send::<NodeSetNameRequest>(
4462 (priority, name),
4463 0x77a41bb6217e2443,
4464 fidl::encoding::DynamicFlags::empty(),
4465 )
4466 }
4467
4468 /// Set information about the current client that can be used by sysmem to
4469 /// help debug leaking memory and hangs waiting for constraints. |name| can
4470 /// be an arbitrary string, but the current process name (see
4471 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
4472 /// arbitrary id, but the current process ID (see
4473 /// fsl::GetCurrentProcessKoid()) is a good default.
4474 ///
4475 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
4476 /// indicate which client is closing their channel first, leading to
4477 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
4478 /// over, but if happening earlier than expected, the
4479 /// client-channel-specific name can help diagnose where the failure is
4480 /// first coming from, from sysmem's point of view).
4481 ///
4482 /// By default (unless overriden by this message or using
4483 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
4484 /// parent Node at the time the child Node is created. While this can be
4485 /// better than nothing, it's often better for each participant to use
4486 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
4487 /// info directly relevant to the current client. Also, SetVerboseLogging()
4488 /// can be used to help disambiguate if a Node is suspected of having info
4489 /// that was copied from its parent.
4490 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
4491 self.client.send::<NodeSetDebugClientInfoRequest>(
4492 (name, id),
4493 0x7275759070eb5ee2,
4494 fidl::encoding::DynamicFlags::empty(),
4495 )
4496 }
4497
4498 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
4499 /// after creating a collection. Clients can call this method to change
4500 /// when the log is printed. If multiple client set the deadline, it's
4501 /// unspecified which deadline will take effect.
4502 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
4503 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
4504 (deadline,),
4505 0x46d38f4772638867,
4506 fidl::encoding::DynamicFlags::empty(),
4507 )
4508 }
4509
4510 /// Verbose logging includes constraints set via SetConstraints() from each
4511 /// client along with info set via SetDebugClientInfo() and the structure of
4512 /// the tree of Node(s).
4513 ///
4514 /// Normally sysmem prints only a single line complaint when aggregation
4515 /// fails, with just the specific detailed reason that aggregation failed,
4516 /// with minimal context. While this is often enough to diagnose a problem
4517 /// if only a small change was made and the system had been working before
4518 /// the small change, it's often not particularly helpful for getting a new
4519 /// buffer collection to work for the first time. Especially with more
4520 /// complex trees of nodes, involving things like AttachToken(),
4521 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
4522 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
4523 /// looks like and why it's failing a logical allocation, or why a tree or
4524 /// sub-tree is failing sooner than expected.
4525 ///
4526 /// The intent of the extra logging is to be acceptable from a performance
4527 /// point of view, if only enabled on a low number of buffer collections.
4528 /// If we're not tracking down a bug, we shouldn't send this message.
4529 ///
4530 /// If too many participants leave verbose logging enabled, we may end up
4531 /// needing to require that system-wide sysmem verbose logging be permitted
4532 /// via some other setting, to avoid sysmem spamming the log too much due to
4533 /// this message.
4534 ///
4535 /// This may be a NOP for some nodes due to intentional policy associated
4536 /// with the node, if we don't trust a node enough to let it turn on verbose
4537 /// logging.
4538 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
4539 self.client.send::<fidl::encoding::EmptyPayload>(
4540 (),
4541 0x6bfbe2cf1701d288,
4542 fidl::encoding::DynamicFlags::empty(),
4543 )
4544 }
4545
4546 /// This gets an event handle that can be used as a parameter to
4547 /// IsAlternateFor() called on any Node. The client will not be granted the
4548 /// right to signal this event, as this handle should only be used as proof
4549 /// that the client obtained this handle from this Node.
4550 ///
4551 /// Because this is a get not a set, no Sync() is needed between the
4552 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
4553 /// potentially being on different channels.
4554 ///
4555 /// See also IsAlternateFor().
4556 pub fn r#get_node_ref(
4557 &self,
4558 ___deadline: zx::MonotonicInstant,
4559 ) -> Result<fidl::Event, fidl::Error> {
4560 let _response =
4561 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
4562 (),
4563 0x467b7c75c35c3b84,
4564 fidl::encoding::DynamicFlags::empty(),
4565 ___deadline,
4566 )?;
4567 Ok(_response.node_ref)
4568 }
4569
4570 /// This checks whether the calling node is in a subtree rooted at a
4571 /// different child token of a common parent BufferCollectionTokenGroup, in
4572 /// relation to the passed-in node_ref.
4573 ///
4574 /// This call is for assisting with admission control de-duplication, and
4575 /// with debugging.
4576 ///
4577 /// The node_ref must be obtained using GetNodeRef() of a
4578 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
4579 ///
4580 /// The node_ref can be a duplicated handle; it's not necessary to call
4581 /// GetNodeRef() for every call to IsAlternateFor().
4582 ///
4583 /// If a calling token may not actually be a valid token at all due to
4584 /// a potentially hostile/untrusted provider of the token, call
4585 /// ValidateBufferCollectionToken() first instead of potentially getting
4586 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
4587 /// token not being a real token (not really talking to sysmem). Another
4588 /// option is to call BindSharedCollection with this token first which also
4589 /// validates the token along with converting it to a BufferCollection, then
4590 /// call BufferCollection IsAlternateFor().
4591 ///
4592 /// error values:
4593 ///
4594 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
4595 /// buffer collection as the calling Node. Before logical allocation and
4596 /// within the same logical allocation sub-tree, this essentially means that
4597 /// the node_ref was never part of this logical buffer collection, since
4598 /// before logical allocation all node_refs that come into existence remain
4599 /// in existence at least until logical allocation (including Node(s) that
4600 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
4601 /// to be returned, this Node's channel needs to still be connected server
4602 /// side, which won't be the case if the whole logical allocation has
4603 /// failed. After logical allocation or in a different logical allocation
4604 /// sub-tree there are additional potential reasons for this error. For
4605 /// example a different logical allocation (separated from this Node(s)
4606 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
4607 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
4608 /// exist and may select a different child sub-tree than the sub-tree the
4609 /// node_ref is in causing deletion of the node_ref Node. The only time
4610 /// sysmem keeps a Node around after that Node has no corresponding channel
4611 /// is when Close() is used and the Node's sub-tree has not yet failed.
4612 /// Another reason for this error is if the node_ref is an eventpair handle
4613 /// with sufficient rights, but isn't actually a real node_ref obtained from
4614 /// GetNodeRef().
4615 ///
4616 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
4617 /// eventpair handle, or doesn't have the needed rights expected on a real
4618 /// node_ref.
4619 ///
4620 /// No other failing status codes are returned by this call. However,
4621 /// sysmem may add additional codes in future, so the client should have
4622 /// sensible default handling for any failing status code.
4623 ///
4624 /// On success, is_alternate has the following meaning:
4625 /// * true - The first parent node in common between the calling node and
4626 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
4627 /// the calling Node and the node_ref Node will _not_ have both their
4628 /// constraints apply - rather sysmem will choose one or the other of
4629 /// the constraints - never both. This is because only one child of
4630 /// a BufferCollectionTokenGroup is selected during logical allocation,
4631 /// with only that one child's sub-tree contributing to constraints
4632 /// aggregation.
4633 /// * false - The first parent node in common between the calling Node and
4634 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
4635 /// this means the first parent node in common is a
4636 /// BufferCollectionToken or BufferCollection (regardless of not
4637 /// Close()ed or Close()ed). This means that the calling Node and the
4638 /// node_ref Node _may_ have both their constraints apply during
4639 /// constraints aggregation of the logical allocation, if both Node(s)
4640 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
4641 /// In this case, there is no BufferCollectionTokenGroup that will
4642 /// directly prevent the two Node(s) from both being selected and their
4643 /// constraints both aggregated, but even when false, one or both
4644 /// Node(s) may still be eliminated from consideration if one or both
4645 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
4646 /// which selects a child sub-tree other than the sub-tree containing
4647 /// the calling Node or node_ref Node.
4648 pub fn r#is_alternate_for(
4649 &self,
4650 mut node_ref: fidl::Event,
4651 ___deadline: zx::MonotonicInstant,
4652 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
4653 let _response = self.client.send_query::<
4654 NodeIsAlternateForRequest,
4655 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
4656 >(
4657 (node_ref,),
4658 0x33a2a7aff2776c07,
4659 fidl::encoding::DynamicFlags::empty(),
4660 ___deadline,
4661 )?;
4662 Ok(_response.map(|x| x.is_alternate))
4663 }
4664
4665 /// This method can be used to add more participants prior to creating a
4666 /// shared BufferCollection. A new token will be returned for each entry in
4667 /// the `rights_attenuation_masks` array. The return value is the client
4668 /// ends of each new participant token.
4669 ///
4670 /// If the calling token may not actually be a valid token at all due to
4671 /// a potentially hostile/untrusted provider of the token, consider using
4672 /// ValidateBufferCollectionToken() first instead of potentially getting
4673 /// stuck indefinitely if DuplicateSync() never responds due to the calling
4674 /// token not being a real token.
4675 ///
4676 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
4677 /// after calling this method.
4678 ///
4679 /// All tokens must be turned in via BindSharedCollection() or Close() for a
4680 /// BufferCollection to be successfully created.
4681 ///
4682 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
4683 /// will be absent in the buffer VMO rights obtainable via the corresponding
4684 /// returned token. This allows an initiator or intermediary participant to
4685 /// attenuate the rights available to a participant. This does not allow a
4686 /// participant to gain rights that the participant doesn't already have.
4687 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
4688 /// attenuation should be applied.
4689 pub fn r#duplicate_sync(
4690 &self,
4691 mut rights_attenuation_masks: &[fidl::Rights],
4692 ___deadline: zx::MonotonicInstant,
4693 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error> {
4694 let _response = self.client.send_query::<
4695 BufferCollectionTokenDuplicateSyncRequest,
4696 BufferCollectionTokenDuplicateSyncResponse,
4697 >(
4698 (rights_attenuation_masks,),
4699 0x49ed7ab7cc19f18,
4700 fidl::encoding::DynamicFlags::empty(),
4701 ___deadline,
4702 )?;
4703 Ok(_response.tokens)
4704 }
4705
4706 /// This method can be used to add a participant prior to creating a shared
4707 /// BufferCollection. It should only be used instead of DuplicateSync in
4708 /// performance sensitive cases where it would be undesireable to wait for
4709 /// sysmem to respond as part of each duplicate.
4710 ///
4711 /// After sending one or more Duplicate() messages, and before sending the
4712 /// created tokens to other participants (or to other Allocator channels),
4713 /// the client should send a Sync() and wait for its response. The Sync()
4714 /// call can be made on the token, or on the BufferCollection obtained by
4715 /// passing this token to BindSharedCollection(). Either will ensure that
4716 /// the server knows about the tokens created via Duplicate() before the
4717 /// other participant sends the token to the server via separate Allocator
4718 /// channel.
4719 ///
4720 /// All tokens must be turned in via BindSharedCollection() or Close() for a
4721 /// BufferCollection to be successfully created.
4722 ///
4723 /// When a client calls BindSharedCollection() to turn in a
4724 /// BufferCollectionToken, the server will process all Duplicate() messages
4725 /// before closing down the BufferCollectionToken. This allows the client
4726 /// to Duplicate() and immediately turn in the BufferCollectionToken using
4727 /// BindSharedCollection, then later transfer the client end of token_request
4728 /// to another participant - the server will notice the existence of the
4729 /// token_request before considering this BufferCollectionToken fully closed.
4730 ///
4731 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
4732 /// absent in the buffer VMO rights obtainable via the client end of
4733 /// token_request. This allows an initiator or intermediary participant to
4734 /// attenuate the rights available to a participant. This does not allow a
4735 /// participant to gain rights that the participant doesn't already have.
4736 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
4737 /// attenuation should be applied.
4738 ///
4739 /// These values for rights_attenuation_mask result in no attenuation:
4740 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
4741 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
4742 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
4743 ///
4744 /// `token_request` is the server end of a BufferCollectionToken channel.
4745 /// The client end of this channel acts as another participant in creating the
4746 /// shared BufferCollection.
4747 pub fn r#duplicate(
4748 &self,
4749 mut rights_attenuation_mask: u32,
4750 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
4751 ) -> Result<(), fidl::Error> {
4752 self.client.send::<BufferCollectionTokenDuplicateRequest>(
4753 (rights_attenuation_mask, token_request),
4754 0x2f9f81bdde4b7292,
4755 fidl::encoding::DynamicFlags::empty(),
4756 )
4757 }
4758
4759 /// A dispensable token can fail after buffers are logically allocated
4760 /// without causing failure of its parent (if any).
4761 ///
4762 /// The dispensable token participates in constraints aggregation along with
4763 /// its parent before logical buffer allocation. If the dispensable token
4764 /// fails before buffers are logically allocated, the failure propagates to
4765 /// the dispensable token's parent.
4766 ///
4767 /// After buffers are logically allocated, failure of the dispensable token
4768 /// (or any child of the dispensable token) does not propagate to the
4769 /// dispensable token's parent. Failure does propagate from a normal
4770 /// child of a dispensable token to the dispensable token. Failure
4771 /// of a child is blocked from reaching its parent if the child is attached,
4772 /// or if the child is dispensable and the failure occurred after logical
4773 /// allocation.
4774 ///
4775 /// A dispensable token can be used in cases where a participant needs to
4776 /// provide constraints, but after buffers are allocated, the participant
4777 /// can fail without causing buffer collection failure from the parent's
4778 /// point of view.
4779 ///
4780 /// In contrast, AttachToken() can be used to create a token which does not
4781 /// participate in constraints aggregation with its parent, and whose
4782 /// failure at any time does not propagate to its parent, and whose delay
4783 /// providing constraints does not prevent the parent from completing its
4784 /// buffer allocation.
4785 ///
4786 /// An initiator may in some scenarios choose to initially use a dispensable
4787 /// token for a given instance of a participant, and then later if the first
4788 /// instance of that participant fails, a new second instance of that
4789 /// participant my be given a token created with AttachToken().
4790 ///
4791 /// If a client uses this message, the client should not rely on the
4792 /// client's own BufferCollectionToken or BufferCollection channel to close
4793 /// from the server end due to abrupt failure of any BufferCollectionToken
4794 /// or BufferCollection that the client has SetDispensable() and given out
4795 /// to another process. For this reason, the client should take extra care
4796 /// to notice failure of that other process via other means.
4797 ///
4798 /// While it is possible (and potentially useful) to SetDispensable() on a
4799 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
4800 /// replace a failed dispensable token that was a direct child of a group
4801 /// with a new token using AttachToken() (since there's no AttachToken() on
4802 /// a group). Instead, to enable AttachToken() replacement in this case,
4803 /// create an additional non-dispensable token (node) that's a direct child
4804 /// of the group and make the existing dispensable token a child of the
4805 /// additional token (node). This way, the additional token (node) that is
4806 /// a direct child of the group has BufferCollection.AttachToken() which can
4807 /// be used to replace the failed dispensable token.
4808 ///
4809 /// SetDispensable() on an already-dispensable token is idempotent.
4810 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
4811 self.client.send::<fidl::encoding::EmptyPayload>(
4812 (),
4813 0x76e4ec34fc2cf5b3,
4814 fidl::encoding::DynamicFlags::empty(),
4815 )
4816 }
4817
4818 /// Most sysmem clients and many participants don't need to care about this
4819 /// message or about BufferCollectionTokenGroup(s) in general.
4820 ///
4821 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
4822 /// tokens. The child tokens which are not selected during aggregation will
4823 /// fail (close), which a potential participant should notice when their
4824 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
4825 /// participant to clean up the speculative usage that didn't end up
4826 /// happening (similarly to a normal BufferCollection server end closing
4827 /// on failure of a logical buffer collection).
4828 ///
4829 /// See comments on protocol BufferCollectionTokenGroup.
4830 ///
4831 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
4832 /// applied to the whole group can be achieved with a token for this purpose
4833 /// as a direct parent of the group.
4834 ///
4835 /// group_request - the server end of a BufferCollectionTokenGroup channel
4836 /// to be served by sysmem.
4837 pub fn r#create_buffer_collection_token_group(
4838 &self,
4839 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
4840 ) -> Result<(), fidl::Error> {
4841 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
4842 (group_request,),
4843 0x2f6243e05f22b9a7,
4844 fidl::encoding::DynamicFlags::empty(),
4845 )
4846 }
4847}
4848
4849#[derive(Debug, Clone)]
4850pub struct BufferCollectionTokenProxy {
4851 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
4852}
4853
4854impl fidl::endpoints::Proxy for BufferCollectionTokenProxy {
4855 type Protocol = BufferCollectionTokenMarker;
4856
4857 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
4858 Self::new(inner)
4859 }
4860
4861 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
4862 self.client.into_channel().map_err(|client| Self { client })
4863 }
4864
4865 fn as_channel(&self) -> &::fidl::AsyncChannel {
4866 self.client.as_channel()
4867 }
4868}
4869
4870impl BufferCollectionTokenProxy {
4871 /// Create a new Proxy for fuchsia.sysmem/BufferCollectionToken.
4872 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
4873 let protocol_name =
4874 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
4875 Self { client: fidl::client::Client::new(channel, protocol_name) }
4876 }
4877
4878 /// Get a Stream of events from the remote end of the protocol.
4879 ///
4880 /// # Panics
4881 ///
4882 /// Panics if the event stream was already taken.
4883 pub fn take_event_stream(&self) -> BufferCollectionTokenEventStream {
4884 BufferCollectionTokenEventStream { event_receiver: self.client.take_event_receiver() }
4885 }
4886
4887 /// Ensure that previous messages, including Duplicate() messages on a
4888 /// token, collection, or group, have been received server side.
4889 ///
4890 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
4891 /// valid sysmem token risks the Sync() hanging forever. See
4892 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
4893 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
4894 /// Another way is to pass the token to BindSharedCollection(), which also
4895 /// validates the token as part of exchanging it for a BufferCollection
4896 /// channel, and BufferCollection Sync() can then be used.
4897 ///
4898 /// After a Sync(), it's then safe to send the client end of token_request
4899 /// to another participant knowing the server will recognize the token when
4900 /// it's sent into BindSharedCollection() by the other participant.
4901 ///
4902 /// Other options include waiting for each token.Duplicate() to complete
4903 /// individually (using separate call to token.Sync() after each), or
4904 /// calling Sync() on BufferCollection after the token has been turned in
4905 /// via BindSharedCollection().
4906 ///
4907 /// Another way to mitigate is to avoid calling Sync() on the token, and
4908 /// instead later deal with potential failure of BufferCollection.Sync() if
4909 /// the original token was invalid. This option can be preferable from a
4910 /// performance point of view, but requires client code to delay sending
4911 /// tokens duplicated from this token until after client code has converted
4912 /// the duplicating token to a BufferCollection and received successful
4913 /// response from BufferCollection.Sync().
4914 ///
4915 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
4916 /// When BufferCollection.Sync() isn't feasible, the caller must already
4917 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
4918 /// hang forever. See ValidateBufferCollectionToken() to check token
4919 /// validity first if the token isn't already known to be (is/was) valid.
4920 pub fn r#sync(
4921 &self,
4922 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
4923 BufferCollectionTokenProxyInterface::r#sync(self)
4924 }
4925
4926 /// On a BufferCollectionToken channel:
4927 ///
4928 /// Normally a participant will convert a BufferCollectionToken into a
4929 /// BufferCollection view, but a participant is also free to Close() the
4930 /// token (and then close the channel immediately or shortly later in
4931 /// response to server closing its end), which avoids causing logical buffer
4932 /// collection failure. Â Normally an unexpected token channel close will
4933 /// cause logical buffer collection failure (the only exceptions being
4934 /// certain cases involving AttachToken() or SetDispensable()).
4935 ///
4936 /// On a BufferCollection channel:
4937 ///
4938 /// By default the server handles unexpected failure of a BufferCollection
4939 /// by failing the whole logical buffer collection. Partly this is to
4940 /// expedite closing VMO handles to reclaim memory when any participant
4941 /// fails. If a participant would like to cleanly close a BufferCollection
4942 /// view without causing logical buffer collection failure, the participant
4943 /// can send Close() before closing the client end of the BufferCollection
4944 /// channel. If this is the last BufferCollection view, the logical buffer
4945 /// collection will still go away. The Close() can occur before or after
4946 /// SetConstraints(). If before SetConstraints(), the buffer collection
4947 /// won't require constraints from this node in order to allocate. If
4948 /// after SetConstraints(), the constraints are retained and aggregated
4949 /// along with any subsequent logical allocation(s), despite the lack of
4950 /// channel connection.
4951 ///
4952 /// On a BufferCollectionTokenGroup channel:
4953 ///
4954 /// By default, unexpected failure of a BufferCollectionTokenGroup will
4955 /// trigger failure of the logical BufferCollectionTokenGroup and will
4956 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
4957 /// channel without failing the logical group or propagating failure, send
4958 /// Close() before closing the channel client endpoint.
4959 ///
4960 /// If Close() occurs before AllChildrenPresent(), the logical buffer
4961 /// collection will still fail despite the Close() (because sysmem can't be
4962 /// sure whether all relevant children were created, so it's ambiguous
4963 /// whether all relevant constraints will be provided to sysmem). If
4964 /// Close() occurs after AllChildrenPresent(), the children and all their
4965 /// constraints remain intact (just as they would if the
4966 /// BufferCollectionTokenGroup channel had remained open), and the close
4967 /// doesn't trigger or propagate failure.
4968 pub fn r#close(&self) -> Result<(), fidl::Error> {
4969 BufferCollectionTokenProxyInterface::r#close(self)
4970 }
4971
4972 /// Set a name for VMOs in this buffer collection. The name may be truncated
4973 /// shorter. The name only affects VMOs allocated after it's set - this call
4974 /// does not rename existing VMOs. If multiple clients set different names
4975 /// then the larger priority value will win.
4976 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
4977 BufferCollectionTokenProxyInterface::r#set_name(self, priority, name)
4978 }
4979
4980 /// Set information about the current client that can be used by sysmem to
4981 /// help debug leaking memory and hangs waiting for constraints. |name| can
4982 /// be an arbitrary string, but the current process name (see
4983 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
4984 /// arbitrary id, but the current process ID (see
4985 /// fsl::GetCurrentProcessKoid()) is a good default.
4986 ///
4987 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
4988 /// indicate which client is closing their channel first, leading to
4989 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
4990 /// over, but if happening earlier than expected, the
4991 /// client-channel-specific name can help diagnose where the failure is
4992 /// first coming from, from sysmem's point of view).
4993 ///
4994 /// By default (unless overriden by this message or using
4995 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
4996 /// parent Node at the time the child Node is created. While this can be
4997 /// better than nothing, it's often better for each participant to use
4998 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
4999 /// info directly relevant to the current client. Also, SetVerboseLogging()
5000 /// can be used to help disambiguate if a Node is suspected of having info
5001 /// that was copied from its parent.
5002 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
5003 BufferCollectionTokenProxyInterface::r#set_debug_client_info(self, name, id)
5004 }
5005
5006 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
5007 /// after creating a collection. Clients can call this method to change
5008 /// when the log is printed. If multiple client set the deadline, it's
5009 /// unspecified which deadline will take effect.
5010 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
5011 BufferCollectionTokenProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
5012 }
5013
5014 /// Verbose logging includes constraints set via SetConstraints() from each
5015 /// client along with info set via SetDebugClientInfo() and the structure of
5016 /// the tree of Node(s).
5017 ///
5018 /// Normally sysmem prints only a single line complaint when aggregation
5019 /// fails, with just the specific detailed reason that aggregation failed,
5020 /// with minimal context. While this is often enough to diagnose a problem
5021 /// if only a small change was made and the system had been working before
5022 /// the small change, it's often not particularly helpful for getting a new
5023 /// buffer collection to work for the first time. Especially with more
5024 /// complex trees of nodes, involving things like AttachToken(),
5025 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
5026 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
5027 /// looks like and why it's failing a logical allocation, or why a tree or
5028 /// sub-tree is failing sooner than expected.
5029 ///
5030 /// The intent of the extra logging is to be acceptable from a performance
5031 /// point of view, if only enabled on a low number of buffer collections.
5032 /// If we're not tracking down a bug, we shouldn't send this message.
5033 ///
5034 /// If too many participants leave verbose logging enabled, we may end up
5035 /// needing to require that system-wide sysmem verbose logging be permitted
5036 /// via some other setting, to avoid sysmem spamming the log too much due to
5037 /// this message.
5038 ///
5039 /// This may be a NOP for some nodes due to intentional policy associated
5040 /// with the node, if we don't trust a node enough to let it turn on verbose
5041 /// logging.
5042 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
5043 BufferCollectionTokenProxyInterface::r#set_verbose_logging(self)
5044 }
5045
5046 /// This gets an event handle that can be used as a parameter to
5047 /// IsAlternateFor() called on any Node. The client will not be granted the
5048 /// right to signal this event, as this handle should only be used as proof
5049 /// that the client obtained this handle from this Node.
5050 ///
5051 /// Because this is a get not a set, no Sync() is needed between the
5052 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
5053 /// potentially being on different channels.
5054 ///
5055 /// See also IsAlternateFor().
5056 pub fn r#get_node_ref(
5057 &self,
5058 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
5059 {
5060 BufferCollectionTokenProxyInterface::r#get_node_ref(self)
5061 }
5062
5063 /// This checks whether the calling node is in a subtree rooted at a
5064 /// different child token of a common parent BufferCollectionTokenGroup, in
5065 /// relation to the passed-in node_ref.
5066 ///
5067 /// This call is for assisting with admission control de-duplication, and
5068 /// with debugging.
5069 ///
5070 /// The node_ref must be obtained using GetNodeRef() of a
5071 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
5072 ///
5073 /// The node_ref can be a duplicated handle; it's not necessary to call
5074 /// GetNodeRef() for every call to IsAlternateFor().
5075 ///
5076 /// If a calling token may not actually be a valid token at all due to
5077 /// a potentially hostile/untrusted provider of the token, call
5078 /// ValidateBufferCollectionToken() first instead of potentially getting
5079 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
5080 /// token not being a real token (not really talking to sysmem). Another
5081 /// option is to call BindSharedCollection with this token first which also
5082 /// validates the token along with converting it to a BufferCollection, then
5083 /// call BufferCollection IsAlternateFor().
5084 ///
5085 /// error values:
5086 ///
5087 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
5088 /// buffer collection as the calling Node. Before logical allocation and
5089 /// within the same logical allocation sub-tree, this essentially means that
5090 /// the node_ref was never part of this logical buffer collection, since
5091 /// before logical allocation all node_refs that come into existence remain
5092 /// in existence at least until logical allocation (including Node(s) that
5093 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
5094 /// to be returned, this Node's channel needs to still be connected server
5095 /// side, which won't be the case if the whole logical allocation has
5096 /// failed. After logical allocation or in a different logical allocation
5097 /// sub-tree there are additional potential reasons for this error. For
5098 /// example a different logical allocation (separated from this Node(s)
5099 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
5100 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
5101 /// exist and may select a different child sub-tree than the sub-tree the
5102 /// node_ref is in causing deletion of the node_ref Node. The only time
5103 /// sysmem keeps a Node around after that Node has no corresponding channel
5104 /// is when Close() is used and the Node's sub-tree has not yet failed.
5105 /// Another reason for this error is if the node_ref is an eventpair handle
5106 /// with sufficient rights, but isn't actually a real node_ref obtained from
5107 /// GetNodeRef().
5108 ///
5109 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
5110 /// eventpair handle, or doesn't have the needed rights expected on a real
5111 /// node_ref.
5112 ///
5113 /// No other failing status codes are returned by this call. However,
5114 /// sysmem may add additional codes in future, so the client should have
5115 /// sensible default handling for any failing status code.
5116 ///
5117 /// On success, is_alternate has the following meaning:
5118 /// * true - The first parent node in common between the calling node and
5119 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
5120 /// the calling Node and the node_ref Node will _not_ have both their
5121 /// constraints apply - rather sysmem will choose one or the other of
5122 /// the constraints - never both. This is because only one child of
5123 /// a BufferCollectionTokenGroup is selected during logical allocation,
5124 /// with only that one child's sub-tree contributing to constraints
5125 /// aggregation.
5126 /// * false - The first parent node in common between the calling Node and
5127 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
5128 /// this means the first parent node in common is a
5129 /// BufferCollectionToken or BufferCollection (regardless of not
5130 /// Close()ed or Close()ed). This means that the calling Node and the
5131 /// node_ref Node _may_ have both their constraints apply during
5132 /// constraints aggregation of the logical allocation, if both Node(s)
5133 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
5134 /// In this case, there is no BufferCollectionTokenGroup that will
5135 /// directly prevent the two Node(s) from both being selected and their
5136 /// constraints both aggregated, but even when false, one or both
5137 /// Node(s) may still be eliminated from consideration if one or both
5138 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
5139 /// which selects a child sub-tree other than the sub-tree containing
5140 /// the calling Node or node_ref Node.
5141 pub fn r#is_alternate_for(
5142 &self,
5143 mut node_ref: fidl::Event,
5144 ) -> fidl::client::QueryResponseFut<
5145 NodeIsAlternateForResult,
5146 fidl::encoding::DefaultFuchsiaResourceDialect,
5147 > {
5148 BufferCollectionTokenProxyInterface::r#is_alternate_for(self, node_ref)
5149 }
5150
5151 /// This method can be used to add more participants prior to creating a
5152 /// shared BufferCollection. A new token will be returned for each entry in
5153 /// the `rights_attenuation_masks` array. The return value is the client
5154 /// ends of each new participant token.
5155 ///
5156 /// If the calling token may not actually be a valid token at all due to
5157 /// a potentially hostile/untrusted provider of the token, consider using
5158 /// ValidateBufferCollectionToken() first instead of potentially getting
5159 /// stuck indefinitely if DuplicateSync() never responds due to the calling
5160 /// token not being a real token.
5161 ///
5162 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
5163 /// after calling this method.
5164 ///
5165 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5166 /// BufferCollection to be successfully created.
5167 ///
5168 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
5169 /// will be absent in the buffer VMO rights obtainable via the corresponding
5170 /// returned token. This allows an initiator or intermediary participant to
5171 /// attenuate the rights available to a participant. This does not allow a
5172 /// participant to gain rights that the participant doesn't already have.
5173 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5174 /// attenuation should be applied.
5175 pub fn r#duplicate_sync(
5176 &self,
5177 mut rights_attenuation_masks: &[fidl::Rights],
5178 ) -> fidl::client::QueryResponseFut<
5179 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
5180 fidl::encoding::DefaultFuchsiaResourceDialect,
5181 > {
5182 BufferCollectionTokenProxyInterface::r#duplicate_sync(self, rights_attenuation_masks)
5183 }
5184
5185 /// This method can be used to add a participant prior to creating a shared
5186 /// BufferCollection. It should only be used instead of DuplicateSync in
5187 /// performance sensitive cases where it would be undesireable to wait for
5188 /// sysmem to respond as part of each duplicate.
5189 ///
5190 /// After sending one or more Duplicate() messages, and before sending the
5191 /// created tokens to other participants (or to other Allocator channels),
5192 /// the client should send a Sync() and wait for its response. The Sync()
5193 /// call can be made on the token, or on the BufferCollection obtained by
5194 /// passing this token to BindSharedCollection(). Either will ensure that
5195 /// the server knows about the tokens created via Duplicate() before the
5196 /// other participant sends the token to the server via separate Allocator
5197 /// channel.
5198 ///
5199 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5200 /// BufferCollection to be successfully created.
5201 ///
5202 /// When a client calls BindSharedCollection() to turn in a
5203 /// BufferCollectionToken, the server will process all Duplicate() messages
5204 /// before closing down the BufferCollectionToken. This allows the client
5205 /// to Duplicate() and immediately turn in the BufferCollectionToken using
5206 /// BindSharedCollection, then later transfer the client end of token_request
5207 /// to another participant - the server will notice the existence of the
5208 /// token_request before considering this BufferCollectionToken fully closed.
5209 ///
5210 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
5211 /// absent in the buffer VMO rights obtainable via the client end of
5212 /// token_request. This allows an initiator or intermediary participant to
5213 /// attenuate the rights available to a participant. This does not allow a
5214 /// participant to gain rights that the participant doesn't already have.
5215 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5216 /// attenuation should be applied.
5217 ///
5218 /// These values for rights_attenuation_mask result in no attenuation:
5219 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
5220 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
5221 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
5222 ///
5223 /// `token_request` is the server end of a BufferCollectionToken channel.
5224 /// The client end of this channel acts as another participant in creating the
5225 /// shared BufferCollection.
5226 pub fn r#duplicate(
5227 &self,
5228 mut rights_attenuation_mask: u32,
5229 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5230 ) -> Result<(), fidl::Error> {
5231 BufferCollectionTokenProxyInterface::r#duplicate(
5232 self,
5233 rights_attenuation_mask,
5234 token_request,
5235 )
5236 }
5237
5238 /// A dispensable token can fail after buffers are logically allocated
5239 /// without causing failure of its parent (if any).
5240 ///
5241 /// The dispensable token participates in constraints aggregation along with
5242 /// its parent before logical buffer allocation. If the dispensable token
5243 /// fails before buffers are logically allocated, the failure propagates to
5244 /// the dispensable token's parent.
5245 ///
5246 /// After buffers are logically allocated, failure of the dispensable token
5247 /// (or any child of the dispensable token) does not propagate to the
5248 /// dispensable token's parent. Failure does propagate from a normal
5249 /// child of a dispensable token to the dispensable token. Failure
5250 /// of a child is blocked from reaching its parent if the child is attached,
5251 /// or if the child is dispensable and the failure occurred after logical
5252 /// allocation.
5253 ///
5254 /// A dispensable token can be used in cases where a participant needs to
5255 /// provide constraints, but after buffers are allocated, the participant
5256 /// can fail without causing buffer collection failure from the parent's
5257 /// point of view.
5258 ///
5259 /// In contrast, AttachToken() can be used to create a token which does not
5260 /// participate in constraints aggregation with its parent, and whose
5261 /// failure at any time does not propagate to its parent, and whose delay
5262 /// providing constraints does not prevent the parent from completing its
5263 /// buffer allocation.
5264 ///
5265 /// An initiator may in some scenarios choose to initially use a dispensable
5266 /// token for a given instance of a participant, and then later if the first
5267 /// instance of that participant fails, a new second instance of that
5268 /// participant my be given a token created with AttachToken().
5269 ///
5270 /// If a client uses this message, the client should not rely on the
5271 /// client's own BufferCollectionToken or BufferCollection channel to close
5272 /// from the server end due to abrupt failure of any BufferCollectionToken
5273 /// or BufferCollection that the client has SetDispensable() and given out
5274 /// to another process. For this reason, the client should take extra care
5275 /// to notice failure of that other process via other means.
5276 ///
5277 /// While it is possible (and potentially useful) to SetDispensable() on a
5278 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
5279 /// replace a failed dispensable token that was a direct child of a group
5280 /// with a new token using AttachToken() (since there's no AttachToken() on
5281 /// a group). Instead, to enable AttachToken() replacement in this case,
5282 /// create an additional non-dispensable token (node) that's a direct child
5283 /// of the group and make the existing dispensable token a child of the
5284 /// additional token (node). This way, the additional token (node) that is
5285 /// a direct child of the group has BufferCollection.AttachToken() which can
5286 /// be used to replace the failed dispensable token.
5287 ///
5288 /// SetDispensable() on an already-dispensable token is idempotent.
5289 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
5290 BufferCollectionTokenProxyInterface::r#set_dispensable(self)
5291 }
5292
5293 /// Most sysmem clients and many participants don't need to care about this
5294 /// message or about BufferCollectionTokenGroup(s) in general.
5295 ///
5296 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
5297 /// tokens. The child tokens which are not selected during aggregation will
5298 /// fail (close), which a potential participant should notice when their
5299 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
5300 /// participant to clean up the speculative usage that didn't end up
5301 /// happening (similarly to a normal BufferCollection server end closing
5302 /// on failure of a logical buffer collection).
5303 ///
5304 /// See comments on protocol BufferCollectionTokenGroup.
5305 ///
5306 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
5307 /// applied to the whole group can be achieved with a token for this purpose
5308 /// as a direct parent of the group.
5309 ///
5310 /// group_request - the server end of a BufferCollectionTokenGroup channel
5311 /// to be served by sysmem.
5312 pub fn r#create_buffer_collection_token_group(
5313 &self,
5314 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
5315 ) -> Result<(), fidl::Error> {
5316 BufferCollectionTokenProxyInterface::r#create_buffer_collection_token_group(
5317 self,
5318 group_request,
5319 )
5320 }
5321}
5322
5323impl BufferCollectionTokenProxyInterface for BufferCollectionTokenProxy {
5324 type SyncResponseFut =
5325 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
5326 fn r#sync(&self) -> Self::SyncResponseFut {
5327 fn _decode(
5328 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5329 ) -> Result<(), fidl::Error> {
5330 let _response = fidl::client::decode_transaction_body::<
5331 fidl::encoding::EmptyPayload,
5332 fidl::encoding::DefaultFuchsiaResourceDialect,
5333 0x4577e238ae26291,
5334 >(_buf?)?;
5335 Ok(_response)
5336 }
5337 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
5338 (),
5339 0x4577e238ae26291,
5340 fidl::encoding::DynamicFlags::empty(),
5341 _decode,
5342 )
5343 }
5344
5345 fn r#close(&self) -> Result<(), fidl::Error> {
5346 self.client.send::<fidl::encoding::EmptyPayload>(
5347 (),
5348 0x5b1d7a4f5681fca7,
5349 fidl::encoding::DynamicFlags::empty(),
5350 )
5351 }
5352
5353 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
5354 self.client.send::<NodeSetNameRequest>(
5355 (priority, name),
5356 0x77a41bb6217e2443,
5357 fidl::encoding::DynamicFlags::empty(),
5358 )
5359 }
5360
5361 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
5362 self.client.send::<NodeSetDebugClientInfoRequest>(
5363 (name, id),
5364 0x7275759070eb5ee2,
5365 fidl::encoding::DynamicFlags::empty(),
5366 )
5367 }
5368
5369 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
5370 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
5371 (deadline,),
5372 0x46d38f4772638867,
5373 fidl::encoding::DynamicFlags::empty(),
5374 )
5375 }
5376
5377 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
5378 self.client.send::<fidl::encoding::EmptyPayload>(
5379 (),
5380 0x6bfbe2cf1701d288,
5381 fidl::encoding::DynamicFlags::empty(),
5382 )
5383 }
5384
5385 type GetNodeRefResponseFut =
5386 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
5387 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
5388 fn _decode(
5389 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5390 ) -> Result<fidl::Event, fidl::Error> {
5391 let _response = fidl::client::decode_transaction_body::<
5392 NodeGetNodeRefResponse,
5393 fidl::encoding::DefaultFuchsiaResourceDialect,
5394 0x467b7c75c35c3b84,
5395 >(_buf?)?;
5396 Ok(_response.node_ref)
5397 }
5398 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
5399 (),
5400 0x467b7c75c35c3b84,
5401 fidl::encoding::DynamicFlags::empty(),
5402 _decode,
5403 )
5404 }
5405
5406 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
5407 NodeIsAlternateForResult,
5408 fidl::encoding::DefaultFuchsiaResourceDialect,
5409 >;
5410 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
5411 fn _decode(
5412 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5413 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
5414 let _response = fidl::client::decode_transaction_body::<
5415 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
5416 fidl::encoding::DefaultFuchsiaResourceDialect,
5417 0x33a2a7aff2776c07,
5418 >(_buf?)?;
5419 Ok(_response.map(|x| x.is_alternate))
5420 }
5421 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
5422 (node_ref,),
5423 0x33a2a7aff2776c07,
5424 fidl::encoding::DynamicFlags::empty(),
5425 _decode,
5426 )
5427 }
5428
5429 type DuplicateSyncResponseFut = fidl::client::QueryResponseFut<
5430 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
5431 fidl::encoding::DefaultFuchsiaResourceDialect,
5432 >;
5433 fn r#duplicate_sync(
5434 &self,
5435 mut rights_attenuation_masks: &[fidl::Rights],
5436 ) -> Self::DuplicateSyncResponseFut {
5437 fn _decode(
5438 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5439 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error>
5440 {
5441 let _response = fidl::client::decode_transaction_body::<
5442 BufferCollectionTokenDuplicateSyncResponse,
5443 fidl::encoding::DefaultFuchsiaResourceDialect,
5444 0x49ed7ab7cc19f18,
5445 >(_buf?)?;
5446 Ok(_response.tokens)
5447 }
5448 self.client.send_query_and_decode::<
5449 BufferCollectionTokenDuplicateSyncRequest,
5450 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
5451 >(
5452 (rights_attenuation_masks,),
5453 0x49ed7ab7cc19f18,
5454 fidl::encoding::DynamicFlags::empty(),
5455 _decode,
5456 )
5457 }
5458
5459 fn r#duplicate(
5460 &self,
5461 mut rights_attenuation_mask: u32,
5462 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5463 ) -> Result<(), fidl::Error> {
5464 self.client.send::<BufferCollectionTokenDuplicateRequest>(
5465 (rights_attenuation_mask, token_request),
5466 0x2f9f81bdde4b7292,
5467 fidl::encoding::DynamicFlags::empty(),
5468 )
5469 }
5470
5471 fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
5472 self.client.send::<fidl::encoding::EmptyPayload>(
5473 (),
5474 0x76e4ec34fc2cf5b3,
5475 fidl::encoding::DynamicFlags::empty(),
5476 )
5477 }
5478
5479 fn r#create_buffer_collection_token_group(
5480 &self,
5481 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
5482 ) -> Result<(), fidl::Error> {
5483 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
5484 (group_request,),
5485 0x2f6243e05f22b9a7,
5486 fidl::encoding::DynamicFlags::empty(),
5487 )
5488 }
5489}
5490
5491pub struct BufferCollectionTokenEventStream {
5492 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
5493}
5494
5495impl std::marker::Unpin for BufferCollectionTokenEventStream {}
5496
5497impl futures::stream::FusedStream for BufferCollectionTokenEventStream {
5498 fn is_terminated(&self) -> bool {
5499 self.event_receiver.is_terminated()
5500 }
5501}
5502
5503impl futures::Stream for BufferCollectionTokenEventStream {
5504 type Item = Result<BufferCollectionTokenEvent, fidl::Error>;
5505
5506 fn poll_next(
5507 mut self: std::pin::Pin<&mut Self>,
5508 cx: &mut std::task::Context<'_>,
5509 ) -> std::task::Poll<Option<Self::Item>> {
5510 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
5511 &mut self.event_receiver,
5512 cx
5513 )?) {
5514 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenEvent::decode(buf))),
5515 None => std::task::Poll::Ready(None),
5516 }
5517 }
5518}
5519
5520#[derive(Debug)]
5521pub enum BufferCollectionTokenEvent {}
5522
5523impl BufferCollectionTokenEvent {
5524 /// Decodes a message buffer as a [`BufferCollectionTokenEvent`].
5525 fn decode(
5526 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
5527 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
5528 let (bytes, _handles) = buf.split_mut();
5529 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
5530 debug_assert_eq!(tx_header.tx_id, 0);
5531 match tx_header.ordinal {
5532 _ => Err(fidl::Error::UnknownOrdinal {
5533 ordinal: tx_header.ordinal,
5534 protocol_name:
5535 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
5536 }),
5537 }
5538 }
5539}
5540
5541/// A Stream of incoming requests for fuchsia.sysmem/BufferCollectionToken.
5542pub struct BufferCollectionTokenRequestStream {
5543 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
5544 is_terminated: bool,
5545}
5546
5547impl std::marker::Unpin for BufferCollectionTokenRequestStream {}
5548
5549impl futures::stream::FusedStream for BufferCollectionTokenRequestStream {
5550 fn is_terminated(&self) -> bool {
5551 self.is_terminated
5552 }
5553}
5554
5555impl fidl::endpoints::RequestStream for BufferCollectionTokenRequestStream {
5556 type Protocol = BufferCollectionTokenMarker;
5557 type ControlHandle = BufferCollectionTokenControlHandle;
5558
5559 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
5560 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
5561 }
5562
5563 fn control_handle(&self) -> Self::ControlHandle {
5564 BufferCollectionTokenControlHandle { inner: self.inner.clone() }
5565 }
5566
5567 fn into_inner(
5568 self,
5569 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
5570 {
5571 (self.inner, self.is_terminated)
5572 }
5573
5574 fn from_inner(
5575 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
5576 is_terminated: bool,
5577 ) -> Self {
5578 Self { inner, is_terminated }
5579 }
5580}
5581
5582impl futures::Stream for BufferCollectionTokenRequestStream {
5583 type Item = Result<BufferCollectionTokenRequest, fidl::Error>;
5584
5585 fn poll_next(
5586 mut self: std::pin::Pin<&mut Self>,
5587 cx: &mut std::task::Context<'_>,
5588 ) -> std::task::Poll<Option<Self::Item>> {
5589 let this = &mut *self;
5590 if this.inner.check_shutdown(cx) {
5591 this.is_terminated = true;
5592 return std::task::Poll::Ready(None);
5593 }
5594 if this.is_terminated {
5595 panic!("polled BufferCollectionTokenRequestStream after completion");
5596 }
5597 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
5598 |bytes, handles| {
5599 match this.inner.channel().read_etc(cx, bytes, handles) {
5600 std::task::Poll::Ready(Ok(())) => {}
5601 std::task::Poll::Pending => return std::task::Poll::Pending,
5602 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
5603 this.is_terminated = true;
5604 return std::task::Poll::Ready(None);
5605 }
5606 std::task::Poll::Ready(Err(e)) => {
5607 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
5608 e.into(),
5609 ))))
5610 }
5611 }
5612
5613 // A message has been received from the channel
5614 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
5615
5616 std::task::Poll::Ready(Some(match header.ordinal {
5617 0x4577e238ae26291 => {
5618 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5619 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5620 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5621 let control_handle = BufferCollectionTokenControlHandle {
5622 inner: this.inner.clone(),
5623 };
5624 Ok(BufferCollectionTokenRequest::Sync {
5625 responder: BufferCollectionTokenSyncResponder {
5626 control_handle: std::mem::ManuallyDrop::new(control_handle),
5627 tx_id: header.tx_id,
5628 },
5629 })
5630 }
5631 0x5b1d7a4f5681fca7 => {
5632 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5633 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5634 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5635 let control_handle = BufferCollectionTokenControlHandle {
5636 inner: this.inner.clone(),
5637 };
5638 Ok(BufferCollectionTokenRequest::Close {
5639 control_handle,
5640 })
5641 }
5642 0x77a41bb6217e2443 => {
5643 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5644 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5645 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
5646 let control_handle = BufferCollectionTokenControlHandle {
5647 inner: this.inner.clone(),
5648 };
5649 Ok(BufferCollectionTokenRequest::SetName {priority: req.priority,
5650name: req.name,
5651
5652 control_handle,
5653 })
5654 }
5655 0x7275759070eb5ee2 => {
5656 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5657 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5658 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
5659 let control_handle = BufferCollectionTokenControlHandle {
5660 inner: this.inner.clone(),
5661 };
5662 Ok(BufferCollectionTokenRequest::SetDebugClientInfo {name: req.name,
5663id: req.id,
5664
5665 control_handle,
5666 })
5667 }
5668 0x46d38f4772638867 => {
5669 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5670 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5671 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
5672 let control_handle = BufferCollectionTokenControlHandle {
5673 inner: this.inner.clone(),
5674 };
5675 Ok(BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {deadline: req.deadline,
5676
5677 control_handle,
5678 })
5679 }
5680 0x6bfbe2cf1701d288 => {
5681 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5682 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5683 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5684 let control_handle = BufferCollectionTokenControlHandle {
5685 inner: this.inner.clone(),
5686 };
5687 Ok(BufferCollectionTokenRequest::SetVerboseLogging {
5688 control_handle,
5689 })
5690 }
5691 0x467b7c75c35c3b84 => {
5692 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5693 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5694 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5695 let control_handle = BufferCollectionTokenControlHandle {
5696 inner: this.inner.clone(),
5697 };
5698 Ok(BufferCollectionTokenRequest::GetNodeRef {
5699 responder: BufferCollectionTokenGetNodeRefResponder {
5700 control_handle: std::mem::ManuallyDrop::new(control_handle),
5701 tx_id: header.tx_id,
5702 },
5703 })
5704 }
5705 0x33a2a7aff2776c07 => {
5706 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5707 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5708 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
5709 let control_handle = BufferCollectionTokenControlHandle {
5710 inner: this.inner.clone(),
5711 };
5712 Ok(BufferCollectionTokenRequest::IsAlternateFor {node_ref: req.node_ref,
5713
5714 responder: BufferCollectionTokenIsAlternateForResponder {
5715 control_handle: std::mem::ManuallyDrop::new(control_handle),
5716 tx_id: header.tx_id,
5717 },
5718 })
5719 }
5720 0x49ed7ab7cc19f18 => {
5721 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5722 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5723 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateSyncRequest>(&header, _body_bytes, handles, &mut req)?;
5724 let control_handle = BufferCollectionTokenControlHandle {
5725 inner: this.inner.clone(),
5726 };
5727 Ok(BufferCollectionTokenRequest::DuplicateSync {rights_attenuation_masks: req.rights_attenuation_masks,
5728
5729 responder: BufferCollectionTokenDuplicateSyncResponder {
5730 control_handle: std::mem::ManuallyDrop::new(control_handle),
5731 tx_id: header.tx_id,
5732 },
5733 })
5734 }
5735 0x2f9f81bdde4b7292 => {
5736 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5737 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5738 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateRequest>(&header, _body_bytes, handles, &mut req)?;
5739 let control_handle = BufferCollectionTokenControlHandle {
5740 inner: this.inner.clone(),
5741 };
5742 Ok(BufferCollectionTokenRequest::Duplicate {rights_attenuation_mask: req.rights_attenuation_mask,
5743token_request: req.token_request,
5744
5745 control_handle,
5746 })
5747 }
5748 0x76e4ec34fc2cf5b3 => {
5749 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5750 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5751 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5752 let control_handle = BufferCollectionTokenControlHandle {
5753 inner: this.inner.clone(),
5754 };
5755 Ok(BufferCollectionTokenRequest::SetDispensable {
5756 control_handle,
5757 })
5758 }
5759 0x2f6243e05f22b9a7 => {
5760 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5761 let mut req = fidl::new_empty!(BufferCollectionTokenCreateBufferCollectionTokenGroupRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5762 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(&header, _body_bytes, handles, &mut req)?;
5763 let control_handle = BufferCollectionTokenControlHandle {
5764 inner: this.inner.clone(),
5765 };
5766 Ok(BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {group_request: req.group_request,
5767
5768 control_handle,
5769 })
5770 }
5771 _ => Err(fidl::Error::UnknownOrdinal {
5772 ordinal: header.ordinal,
5773 protocol_name: <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
5774 }),
5775 }))
5776 },
5777 )
5778 }
5779}
5780
5781/// A BufferCollectionToken is not a BufferCollection, but rather a way to
5782/// identify a potential shared BufferCollection prior to the BufferCollection
5783/// being allocated.
5784///
5785/// We use a channel for the BufferCollectionToken instead of a single eventpair
5786/// (pair) because this way we can detect error conditions like a participant
5787/// dying mid-create.
5788///
5789/// The fuchsia.sysmem.BufferCollectionToken type is not yet deprecated due to
5790/// its use in some other protocols (for now), but all the internals of
5791/// fuchsia.sysmem.BufferCollectionToken are deprecated. Token channels serve
5792/// both fuchsia.sysmem.BufferCollectionToken and
5793/// fuchsia.sysmem2.BufferCollectionToken.
5794///
5795/// This protocol will be deprecated once other protocols have switched their
5796/// token fields to fuchsia.sysmem2.BufferCollectionToken.
5797#[derive(Debug)]
5798pub enum BufferCollectionTokenRequest {
5799 /// Ensure that previous messages, including Duplicate() messages on a
5800 /// token, collection, or group, have been received server side.
5801 ///
5802 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
5803 /// valid sysmem token risks the Sync() hanging forever. See
5804 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
5805 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
5806 /// Another way is to pass the token to BindSharedCollection(), which also
5807 /// validates the token as part of exchanging it for a BufferCollection
5808 /// channel, and BufferCollection Sync() can then be used.
5809 ///
5810 /// After a Sync(), it's then safe to send the client end of token_request
5811 /// to another participant knowing the server will recognize the token when
5812 /// it's sent into BindSharedCollection() by the other participant.
5813 ///
5814 /// Other options include waiting for each token.Duplicate() to complete
5815 /// individually (using separate call to token.Sync() after each), or
5816 /// calling Sync() on BufferCollection after the token has been turned in
5817 /// via BindSharedCollection().
5818 ///
5819 /// Another way to mitigate is to avoid calling Sync() on the token, and
5820 /// instead later deal with potential failure of BufferCollection.Sync() if
5821 /// the original token was invalid. This option can be preferable from a
5822 /// performance point of view, but requires client code to delay sending
5823 /// tokens duplicated from this token until after client code has converted
5824 /// the duplicating token to a BufferCollection and received successful
5825 /// response from BufferCollection.Sync().
5826 ///
5827 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
5828 /// When BufferCollection.Sync() isn't feasible, the caller must already
5829 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
5830 /// hang forever. See ValidateBufferCollectionToken() to check token
5831 /// validity first if the token isn't already known to be (is/was) valid.
5832 Sync { responder: BufferCollectionTokenSyncResponder },
5833 /// On a BufferCollectionToken channel:
5834 ///
5835 /// Normally a participant will convert a BufferCollectionToken into a
5836 /// BufferCollection view, but a participant is also free to Close() the
5837 /// token (and then close the channel immediately or shortly later in
5838 /// response to server closing its end), which avoids causing logical buffer
5839 /// collection failure. Â Normally an unexpected token channel close will
5840 /// cause logical buffer collection failure (the only exceptions being
5841 /// certain cases involving AttachToken() or SetDispensable()).
5842 ///
5843 /// On a BufferCollection channel:
5844 ///
5845 /// By default the server handles unexpected failure of a BufferCollection
5846 /// by failing the whole logical buffer collection. Partly this is to
5847 /// expedite closing VMO handles to reclaim memory when any participant
5848 /// fails. If a participant would like to cleanly close a BufferCollection
5849 /// view without causing logical buffer collection failure, the participant
5850 /// can send Close() before closing the client end of the BufferCollection
5851 /// channel. If this is the last BufferCollection view, the logical buffer
5852 /// collection will still go away. The Close() can occur before or after
5853 /// SetConstraints(). If before SetConstraints(), the buffer collection
5854 /// won't require constraints from this node in order to allocate. If
5855 /// after SetConstraints(), the constraints are retained and aggregated
5856 /// along with any subsequent logical allocation(s), despite the lack of
5857 /// channel connection.
5858 ///
5859 /// On a BufferCollectionTokenGroup channel:
5860 ///
5861 /// By default, unexpected failure of a BufferCollectionTokenGroup will
5862 /// trigger failure of the logical BufferCollectionTokenGroup and will
5863 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
5864 /// channel without failing the logical group or propagating failure, send
5865 /// Close() before closing the channel client endpoint.
5866 ///
5867 /// If Close() occurs before AllChildrenPresent(), the logical buffer
5868 /// collection will still fail despite the Close() (because sysmem can't be
5869 /// sure whether all relevant children were created, so it's ambiguous
5870 /// whether all relevant constraints will be provided to sysmem). If
5871 /// Close() occurs after AllChildrenPresent(), the children and all their
5872 /// constraints remain intact (just as they would if the
5873 /// BufferCollectionTokenGroup channel had remained open), and the close
5874 /// doesn't trigger or propagate failure.
5875 Close { control_handle: BufferCollectionTokenControlHandle },
5876 /// Set a name for VMOs in this buffer collection. The name may be truncated
5877 /// shorter. The name only affects VMOs allocated after it's set - this call
5878 /// does not rename existing VMOs. If multiple clients set different names
5879 /// then the larger priority value will win.
5880 SetName { priority: u32, name: String, control_handle: BufferCollectionTokenControlHandle },
5881 /// Set information about the current client that can be used by sysmem to
5882 /// help debug leaking memory and hangs waiting for constraints. |name| can
5883 /// be an arbitrary string, but the current process name (see
5884 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
5885 /// arbitrary id, but the current process ID (see
5886 /// fsl::GetCurrentProcessKoid()) is a good default.
5887 ///
5888 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
5889 /// indicate which client is closing their channel first, leading to
5890 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
5891 /// over, but if happening earlier than expected, the
5892 /// client-channel-specific name can help diagnose where the failure is
5893 /// first coming from, from sysmem's point of view).
5894 ///
5895 /// By default (unless overriden by this message or using
5896 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
5897 /// parent Node at the time the child Node is created. While this can be
5898 /// better than nothing, it's often better for each participant to use
5899 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
5900 /// info directly relevant to the current client. Also, SetVerboseLogging()
5901 /// can be used to help disambiguate if a Node is suspected of having info
5902 /// that was copied from its parent.
5903 SetDebugClientInfo { name: String, id: u64, control_handle: BufferCollectionTokenControlHandle },
5904 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
5905 /// after creating a collection. Clients can call this method to change
5906 /// when the log is printed. If multiple client set the deadline, it's
5907 /// unspecified which deadline will take effect.
5908 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: BufferCollectionTokenControlHandle },
5909 /// Verbose logging includes constraints set via SetConstraints() from each
5910 /// client along with info set via SetDebugClientInfo() and the structure of
5911 /// the tree of Node(s).
5912 ///
5913 /// Normally sysmem prints only a single line complaint when aggregation
5914 /// fails, with just the specific detailed reason that aggregation failed,
5915 /// with minimal context. While this is often enough to diagnose a problem
5916 /// if only a small change was made and the system had been working before
5917 /// the small change, it's often not particularly helpful for getting a new
5918 /// buffer collection to work for the first time. Especially with more
5919 /// complex trees of nodes, involving things like AttachToken(),
5920 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
5921 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
5922 /// looks like and why it's failing a logical allocation, or why a tree or
5923 /// sub-tree is failing sooner than expected.
5924 ///
5925 /// The intent of the extra logging is to be acceptable from a performance
5926 /// point of view, if only enabled on a low number of buffer collections.
5927 /// If we're not tracking down a bug, we shouldn't send this message.
5928 ///
5929 /// If too many participants leave verbose logging enabled, we may end up
5930 /// needing to require that system-wide sysmem verbose logging be permitted
5931 /// via some other setting, to avoid sysmem spamming the log too much due to
5932 /// this message.
5933 ///
5934 /// This may be a NOP for some nodes due to intentional policy associated
5935 /// with the node, if we don't trust a node enough to let it turn on verbose
5936 /// logging.
5937 SetVerboseLogging { control_handle: BufferCollectionTokenControlHandle },
5938 /// This gets an event handle that can be used as a parameter to
5939 /// IsAlternateFor() called on any Node. The client will not be granted the
5940 /// right to signal this event, as this handle should only be used as proof
5941 /// that the client obtained this handle from this Node.
5942 ///
5943 /// Because this is a get not a set, no Sync() is needed between the
5944 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
5945 /// potentially being on different channels.
5946 ///
5947 /// See also IsAlternateFor().
5948 GetNodeRef { responder: BufferCollectionTokenGetNodeRefResponder },
5949 /// This checks whether the calling node is in a subtree rooted at a
5950 /// different child token of a common parent BufferCollectionTokenGroup, in
5951 /// relation to the passed-in node_ref.
5952 ///
5953 /// This call is for assisting with admission control de-duplication, and
5954 /// with debugging.
5955 ///
5956 /// The node_ref must be obtained using GetNodeRef() of a
5957 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
5958 ///
5959 /// The node_ref can be a duplicated handle; it's not necessary to call
5960 /// GetNodeRef() for every call to IsAlternateFor().
5961 ///
5962 /// If a calling token may not actually be a valid token at all due to
5963 /// a potentially hostile/untrusted provider of the token, call
5964 /// ValidateBufferCollectionToken() first instead of potentially getting
5965 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
5966 /// token not being a real token (not really talking to sysmem). Another
5967 /// option is to call BindSharedCollection with this token first which also
5968 /// validates the token along with converting it to a BufferCollection, then
5969 /// call BufferCollection IsAlternateFor().
5970 ///
5971 /// error values:
5972 ///
5973 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
5974 /// buffer collection as the calling Node. Before logical allocation and
5975 /// within the same logical allocation sub-tree, this essentially means that
5976 /// the node_ref was never part of this logical buffer collection, since
5977 /// before logical allocation all node_refs that come into existence remain
5978 /// in existence at least until logical allocation (including Node(s) that
5979 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
5980 /// to be returned, this Node's channel needs to still be connected server
5981 /// side, which won't be the case if the whole logical allocation has
5982 /// failed. After logical allocation or in a different logical allocation
5983 /// sub-tree there are additional potential reasons for this error. For
5984 /// example a different logical allocation (separated from this Node(s)
5985 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
5986 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
5987 /// exist and may select a different child sub-tree than the sub-tree the
5988 /// node_ref is in causing deletion of the node_ref Node. The only time
5989 /// sysmem keeps a Node around after that Node has no corresponding channel
5990 /// is when Close() is used and the Node's sub-tree has not yet failed.
5991 /// Another reason for this error is if the node_ref is an eventpair handle
5992 /// with sufficient rights, but isn't actually a real node_ref obtained from
5993 /// GetNodeRef().
5994 ///
5995 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
5996 /// eventpair handle, or doesn't have the needed rights expected on a real
5997 /// node_ref.
5998 ///
5999 /// No other failing status codes are returned by this call. However,
6000 /// sysmem may add additional codes in future, so the client should have
6001 /// sensible default handling for any failing status code.
6002 ///
6003 /// On success, is_alternate has the following meaning:
6004 /// * true - The first parent node in common between the calling node and
6005 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
6006 /// the calling Node and the node_ref Node will _not_ have both their
6007 /// constraints apply - rather sysmem will choose one or the other of
6008 /// the constraints - never both. This is because only one child of
6009 /// a BufferCollectionTokenGroup is selected during logical allocation,
6010 /// with only that one child's sub-tree contributing to constraints
6011 /// aggregation.
6012 /// * false - The first parent node in common between the calling Node and
6013 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
6014 /// this means the first parent node in common is a
6015 /// BufferCollectionToken or BufferCollection (regardless of not
6016 /// Close()ed or Close()ed). This means that the calling Node and the
6017 /// node_ref Node _may_ have both their constraints apply during
6018 /// constraints aggregation of the logical allocation, if both Node(s)
6019 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
6020 /// In this case, there is no BufferCollectionTokenGroup that will
6021 /// directly prevent the two Node(s) from both being selected and their
6022 /// constraints both aggregated, but even when false, one or both
6023 /// Node(s) may still be eliminated from consideration if one or both
6024 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
6025 /// which selects a child sub-tree other than the sub-tree containing
6026 /// the calling Node or node_ref Node.
6027 IsAlternateFor {
6028 node_ref: fidl::Event,
6029 responder: BufferCollectionTokenIsAlternateForResponder,
6030 },
6031 /// This method can be used to add more participants prior to creating a
6032 /// shared BufferCollection. A new token will be returned for each entry in
6033 /// the `rights_attenuation_masks` array. The return value is the client
6034 /// ends of each new participant token.
6035 ///
6036 /// If the calling token may not actually be a valid token at all due to
6037 /// a potentially hostile/untrusted provider of the token, consider using
6038 /// ValidateBufferCollectionToken() first instead of potentially getting
6039 /// stuck indefinitely if DuplicateSync() never responds due to the calling
6040 /// token not being a real token.
6041 ///
6042 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
6043 /// after calling this method.
6044 ///
6045 /// All tokens must be turned in via BindSharedCollection() or Close() for a
6046 /// BufferCollection to be successfully created.
6047 ///
6048 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
6049 /// will be absent in the buffer VMO rights obtainable via the corresponding
6050 /// returned token. This allows an initiator or intermediary participant to
6051 /// attenuate the rights available to a participant. This does not allow a
6052 /// participant to gain rights that the participant doesn't already have.
6053 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
6054 /// attenuation should be applied.
6055 DuplicateSync {
6056 rights_attenuation_masks: Vec<fidl::Rights>,
6057 responder: BufferCollectionTokenDuplicateSyncResponder,
6058 },
6059 /// This method can be used to add a participant prior to creating a shared
6060 /// BufferCollection. It should only be used instead of DuplicateSync in
6061 /// performance sensitive cases where it would be undesireable to wait for
6062 /// sysmem to respond as part of each duplicate.
6063 ///
6064 /// After sending one or more Duplicate() messages, and before sending the
6065 /// created tokens to other participants (or to other Allocator channels),
6066 /// the client should send a Sync() and wait for its response. The Sync()
6067 /// call can be made on the token, or on the BufferCollection obtained by
6068 /// passing this token to BindSharedCollection(). Either will ensure that
6069 /// the server knows about the tokens created via Duplicate() before the
6070 /// other participant sends the token to the server via separate Allocator
6071 /// channel.
6072 ///
6073 /// All tokens must be turned in via BindSharedCollection() or Close() for a
6074 /// BufferCollection to be successfully created.
6075 ///
6076 /// When a client calls BindSharedCollection() to turn in a
6077 /// BufferCollectionToken, the server will process all Duplicate() messages
6078 /// before closing down the BufferCollectionToken. This allows the client
6079 /// to Duplicate() and immediately turn in the BufferCollectionToken using
6080 /// BindSharedCollection, then later transfer the client end of token_request
6081 /// to another participant - the server will notice the existence of the
6082 /// token_request before considering this BufferCollectionToken fully closed.
6083 ///
6084 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
6085 /// absent in the buffer VMO rights obtainable via the client end of
6086 /// token_request. This allows an initiator or intermediary participant to
6087 /// attenuate the rights available to a participant. This does not allow a
6088 /// participant to gain rights that the participant doesn't already have.
6089 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
6090 /// attenuation should be applied.
6091 ///
6092 /// These values for rights_attenuation_mask result in no attenuation:
6093 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
6094 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
6095 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
6096 ///
6097 /// `token_request` is the server end of a BufferCollectionToken channel.
6098 /// The client end of this channel acts as another participant in creating the
6099 /// shared BufferCollection.
6100 Duplicate {
6101 rights_attenuation_mask: u32,
6102 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
6103 control_handle: BufferCollectionTokenControlHandle,
6104 },
6105 /// A dispensable token can fail after buffers are logically allocated
6106 /// without causing failure of its parent (if any).
6107 ///
6108 /// The dispensable token participates in constraints aggregation along with
6109 /// its parent before logical buffer allocation. If the dispensable token
6110 /// fails before buffers are logically allocated, the failure propagates to
6111 /// the dispensable token's parent.
6112 ///
6113 /// After buffers are logically allocated, failure of the dispensable token
6114 /// (or any child of the dispensable token) does not propagate to the
6115 /// dispensable token's parent. Failure does propagate from a normal
6116 /// child of a dispensable token to the dispensable token. Failure
6117 /// of a child is blocked from reaching its parent if the child is attached,
6118 /// or if the child is dispensable and the failure occurred after logical
6119 /// allocation.
6120 ///
6121 /// A dispensable token can be used in cases where a participant needs to
6122 /// provide constraints, but after buffers are allocated, the participant
6123 /// can fail without causing buffer collection failure from the parent's
6124 /// point of view.
6125 ///
6126 /// In contrast, AttachToken() can be used to create a token which does not
6127 /// participate in constraints aggregation with its parent, and whose
6128 /// failure at any time does not propagate to its parent, and whose delay
6129 /// providing constraints does not prevent the parent from completing its
6130 /// buffer allocation.
6131 ///
6132 /// An initiator may in some scenarios choose to initially use a dispensable
6133 /// token for a given instance of a participant, and then later if the first
6134 /// instance of that participant fails, a new second instance of that
6135 /// participant my be given a token created with AttachToken().
6136 ///
6137 /// If a client uses this message, the client should not rely on the
6138 /// client's own BufferCollectionToken or BufferCollection channel to close
6139 /// from the server end due to abrupt failure of any BufferCollectionToken
6140 /// or BufferCollection that the client has SetDispensable() and given out
6141 /// to another process. For this reason, the client should take extra care
6142 /// to notice failure of that other process via other means.
6143 ///
6144 /// While it is possible (and potentially useful) to SetDispensable() on a
6145 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
6146 /// replace a failed dispensable token that was a direct child of a group
6147 /// with a new token using AttachToken() (since there's no AttachToken() on
6148 /// a group). Instead, to enable AttachToken() replacement in this case,
6149 /// create an additional non-dispensable token (node) that's a direct child
6150 /// of the group and make the existing dispensable token a child of the
6151 /// additional token (node). This way, the additional token (node) that is
6152 /// a direct child of the group has BufferCollection.AttachToken() which can
6153 /// be used to replace the failed dispensable token.
6154 ///
6155 /// SetDispensable() on an already-dispensable token is idempotent.
6156 SetDispensable { control_handle: BufferCollectionTokenControlHandle },
6157 /// Most sysmem clients and many participants don't need to care about this
6158 /// message or about BufferCollectionTokenGroup(s) in general.
6159 ///
6160 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
6161 /// tokens. The child tokens which are not selected during aggregation will
6162 /// fail (close), which a potential participant should notice when their
6163 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
6164 /// participant to clean up the speculative usage that didn't end up
6165 /// happening (similarly to a normal BufferCollection server end closing
6166 /// on failure of a logical buffer collection).
6167 ///
6168 /// See comments on protocol BufferCollectionTokenGroup.
6169 ///
6170 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
6171 /// applied to the whole group can be achieved with a token for this purpose
6172 /// as a direct parent of the group.
6173 ///
6174 /// group_request - the server end of a BufferCollectionTokenGroup channel
6175 /// to be served by sysmem.
6176 CreateBufferCollectionTokenGroup {
6177 group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
6178 control_handle: BufferCollectionTokenControlHandle,
6179 },
6180}
6181
6182impl BufferCollectionTokenRequest {
6183 #[allow(irrefutable_let_patterns)]
6184 pub fn into_sync(self) -> Option<(BufferCollectionTokenSyncResponder)> {
6185 if let BufferCollectionTokenRequest::Sync { responder } = self {
6186 Some((responder))
6187 } else {
6188 None
6189 }
6190 }
6191
6192 #[allow(irrefutable_let_patterns)]
6193 pub fn into_close(self) -> Option<(BufferCollectionTokenControlHandle)> {
6194 if let BufferCollectionTokenRequest::Close { control_handle } = self {
6195 Some((control_handle))
6196 } else {
6197 None
6198 }
6199 }
6200
6201 #[allow(irrefutable_let_patterns)]
6202 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionTokenControlHandle)> {
6203 if let BufferCollectionTokenRequest::SetName { priority, name, control_handle } = self {
6204 Some((priority, name, control_handle))
6205 } else {
6206 None
6207 }
6208 }
6209
6210 #[allow(irrefutable_let_patterns)]
6211 pub fn into_set_debug_client_info(
6212 self,
6213 ) -> Option<(String, u64, BufferCollectionTokenControlHandle)> {
6214 if let BufferCollectionTokenRequest::SetDebugClientInfo { name, id, control_handle } = self
6215 {
6216 Some((name, id, control_handle))
6217 } else {
6218 None
6219 }
6220 }
6221
6222 #[allow(irrefutable_let_patterns)]
6223 pub fn into_set_debug_timeout_log_deadline(
6224 self,
6225 ) -> Option<(i64, BufferCollectionTokenControlHandle)> {
6226 if let BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {
6227 deadline,
6228 control_handle,
6229 } = self
6230 {
6231 Some((deadline, control_handle))
6232 } else {
6233 None
6234 }
6235 }
6236
6237 #[allow(irrefutable_let_patterns)]
6238 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenControlHandle)> {
6239 if let BufferCollectionTokenRequest::SetVerboseLogging { control_handle } = self {
6240 Some((control_handle))
6241 } else {
6242 None
6243 }
6244 }
6245
6246 #[allow(irrefutable_let_patterns)]
6247 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGetNodeRefResponder)> {
6248 if let BufferCollectionTokenRequest::GetNodeRef { responder } = self {
6249 Some((responder))
6250 } else {
6251 None
6252 }
6253 }
6254
6255 #[allow(irrefutable_let_patterns)]
6256 pub fn into_is_alternate_for(
6257 self,
6258 ) -> Option<(fidl::Event, BufferCollectionTokenIsAlternateForResponder)> {
6259 if let BufferCollectionTokenRequest::IsAlternateFor { node_ref, responder } = self {
6260 Some((node_ref, responder))
6261 } else {
6262 None
6263 }
6264 }
6265
6266 #[allow(irrefutable_let_patterns)]
6267 pub fn into_duplicate_sync(
6268 self,
6269 ) -> Option<(Vec<fidl::Rights>, BufferCollectionTokenDuplicateSyncResponder)> {
6270 if let BufferCollectionTokenRequest::DuplicateSync { rights_attenuation_masks, responder } =
6271 self
6272 {
6273 Some((rights_attenuation_masks, responder))
6274 } else {
6275 None
6276 }
6277 }
6278
6279 #[allow(irrefutable_let_patterns)]
6280 pub fn into_duplicate(
6281 self,
6282 ) -> Option<(
6283 u32,
6284 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
6285 BufferCollectionTokenControlHandle,
6286 )> {
6287 if let BufferCollectionTokenRequest::Duplicate {
6288 rights_attenuation_mask,
6289 token_request,
6290 control_handle,
6291 } = self
6292 {
6293 Some((rights_attenuation_mask, token_request, control_handle))
6294 } else {
6295 None
6296 }
6297 }
6298
6299 #[allow(irrefutable_let_patterns)]
6300 pub fn into_set_dispensable(self) -> Option<(BufferCollectionTokenControlHandle)> {
6301 if let BufferCollectionTokenRequest::SetDispensable { control_handle } = self {
6302 Some((control_handle))
6303 } else {
6304 None
6305 }
6306 }
6307
6308 #[allow(irrefutable_let_patterns)]
6309 pub fn into_create_buffer_collection_token_group(
6310 self,
6311 ) -> Option<(
6312 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
6313 BufferCollectionTokenControlHandle,
6314 )> {
6315 if let BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {
6316 group_request,
6317 control_handle,
6318 } = self
6319 {
6320 Some((group_request, control_handle))
6321 } else {
6322 None
6323 }
6324 }
6325
6326 /// Name of the method defined in FIDL
6327 pub fn method_name(&self) -> &'static str {
6328 match *self {
6329 BufferCollectionTokenRequest::Sync { .. } => "sync",
6330 BufferCollectionTokenRequest::Close { .. } => "close",
6331 BufferCollectionTokenRequest::SetName { .. } => "set_name",
6332 BufferCollectionTokenRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
6333 BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline { .. } => {
6334 "set_debug_timeout_log_deadline"
6335 }
6336 BufferCollectionTokenRequest::SetVerboseLogging { .. } => "set_verbose_logging",
6337 BufferCollectionTokenRequest::GetNodeRef { .. } => "get_node_ref",
6338 BufferCollectionTokenRequest::IsAlternateFor { .. } => "is_alternate_for",
6339 BufferCollectionTokenRequest::DuplicateSync { .. } => "duplicate_sync",
6340 BufferCollectionTokenRequest::Duplicate { .. } => "duplicate",
6341 BufferCollectionTokenRequest::SetDispensable { .. } => "set_dispensable",
6342 BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup { .. } => {
6343 "create_buffer_collection_token_group"
6344 }
6345 }
6346 }
6347}
6348
6349#[derive(Debug, Clone)]
6350pub struct BufferCollectionTokenControlHandle {
6351 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
6352}
6353
6354impl fidl::endpoints::ControlHandle for BufferCollectionTokenControlHandle {
6355 fn shutdown(&self) {
6356 self.inner.shutdown()
6357 }
6358 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
6359 self.inner.shutdown_with_epitaph(status)
6360 }
6361
6362 fn is_closed(&self) -> bool {
6363 self.inner.channel().is_closed()
6364 }
6365 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
6366 self.inner.channel().on_closed()
6367 }
6368
6369 #[cfg(target_os = "fuchsia")]
6370 fn signal_peer(
6371 &self,
6372 clear_mask: zx::Signals,
6373 set_mask: zx::Signals,
6374 ) -> Result<(), zx_status::Status> {
6375 use fidl::Peered;
6376 self.inner.channel().signal_peer(clear_mask, set_mask)
6377 }
6378}
6379
6380impl BufferCollectionTokenControlHandle {}
6381
6382#[must_use = "FIDL methods require a response to be sent"]
6383#[derive(Debug)]
6384pub struct BufferCollectionTokenSyncResponder {
6385 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6386 tx_id: u32,
6387}
6388
6389/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6390/// if the responder is dropped without sending a response, so that the client
6391/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6392impl std::ops::Drop for BufferCollectionTokenSyncResponder {
6393 fn drop(&mut self) {
6394 self.control_handle.shutdown();
6395 // Safety: drops once, never accessed again
6396 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6397 }
6398}
6399
6400impl fidl::endpoints::Responder for BufferCollectionTokenSyncResponder {
6401 type ControlHandle = BufferCollectionTokenControlHandle;
6402
6403 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6404 &self.control_handle
6405 }
6406
6407 fn drop_without_shutdown(mut self) {
6408 // Safety: drops once, never accessed again due to mem::forget
6409 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6410 // Prevent Drop from running (which would shut down the channel)
6411 std::mem::forget(self);
6412 }
6413}
6414
6415impl BufferCollectionTokenSyncResponder {
6416 /// Sends a response to the FIDL transaction.
6417 ///
6418 /// Sets the channel to shutdown if an error occurs.
6419 pub fn send(self) -> Result<(), fidl::Error> {
6420 let _result = self.send_raw();
6421 if _result.is_err() {
6422 self.control_handle.shutdown();
6423 }
6424 self.drop_without_shutdown();
6425 _result
6426 }
6427
6428 /// Similar to "send" but does not shutdown the channel if an error occurs.
6429 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
6430 let _result = self.send_raw();
6431 self.drop_without_shutdown();
6432 _result
6433 }
6434
6435 fn send_raw(&self) -> Result<(), fidl::Error> {
6436 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
6437 (),
6438 self.tx_id,
6439 0x4577e238ae26291,
6440 fidl::encoding::DynamicFlags::empty(),
6441 )
6442 }
6443}
6444
6445#[must_use = "FIDL methods require a response to be sent"]
6446#[derive(Debug)]
6447pub struct BufferCollectionTokenGetNodeRefResponder {
6448 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6449 tx_id: u32,
6450}
6451
6452/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6453/// if the responder is dropped without sending a response, so that the client
6454/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6455impl std::ops::Drop for BufferCollectionTokenGetNodeRefResponder {
6456 fn drop(&mut self) {
6457 self.control_handle.shutdown();
6458 // Safety: drops once, never accessed again
6459 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6460 }
6461}
6462
6463impl fidl::endpoints::Responder for BufferCollectionTokenGetNodeRefResponder {
6464 type ControlHandle = BufferCollectionTokenControlHandle;
6465
6466 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6467 &self.control_handle
6468 }
6469
6470 fn drop_without_shutdown(mut self) {
6471 // Safety: drops once, never accessed again due to mem::forget
6472 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6473 // Prevent Drop from running (which would shut down the channel)
6474 std::mem::forget(self);
6475 }
6476}
6477
6478impl BufferCollectionTokenGetNodeRefResponder {
6479 /// Sends a response to the FIDL transaction.
6480 ///
6481 /// Sets the channel to shutdown if an error occurs.
6482 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6483 let _result = self.send_raw(node_ref);
6484 if _result.is_err() {
6485 self.control_handle.shutdown();
6486 }
6487 self.drop_without_shutdown();
6488 _result
6489 }
6490
6491 /// Similar to "send" but does not shutdown the channel if an error occurs.
6492 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6493 let _result = self.send_raw(node_ref);
6494 self.drop_without_shutdown();
6495 _result
6496 }
6497
6498 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6499 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
6500 (node_ref,),
6501 self.tx_id,
6502 0x467b7c75c35c3b84,
6503 fidl::encoding::DynamicFlags::empty(),
6504 )
6505 }
6506}
6507
6508#[must_use = "FIDL methods require a response to be sent"]
6509#[derive(Debug)]
6510pub struct BufferCollectionTokenIsAlternateForResponder {
6511 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6512 tx_id: u32,
6513}
6514
6515/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6516/// if the responder is dropped without sending a response, so that the client
6517/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6518impl std::ops::Drop for BufferCollectionTokenIsAlternateForResponder {
6519 fn drop(&mut self) {
6520 self.control_handle.shutdown();
6521 // Safety: drops once, never accessed again
6522 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6523 }
6524}
6525
6526impl fidl::endpoints::Responder for BufferCollectionTokenIsAlternateForResponder {
6527 type ControlHandle = BufferCollectionTokenControlHandle;
6528
6529 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6530 &self.control_handle
6531 }
6532
6533 fn drop_without_shutdown(mut self) {
6534 // Safety: drops once, never accessed again due to mem::forget
6535 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6536 // Prevent Drop from running (which would shut down the channel)
6537 std::mem::forget(self);
6538 }
6539}
6540
6541impl BufferCollectionTokenIsAlternateForResponder {
6542 /// Sends a response to the FIDL transaction.
6543 ///
6544 /// Sets the channel to shutdown if an error occurs.
6545 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6546 let _result = self.send_raw(result);
6547 if _result.is_err() {
6548 self.control_handle.shutdown();
6549 }
6550 self.drop_without_shutdown();
6551 _result
6552 }
6553
6554 /// Similar to "send" but does not shutdown the channel if an error occurs.
6555 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6556 let _result = self.send_raw(result);
6557 self.drop_without_shutdown();
6558 _result
6559 }
6560
6561 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6562 self.control_handle
6563 .inner
6564 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
6565 result.map(|is_alternate| (is_alternate,)),
6566 self.tx_id,
6567 0x33a2a7aff2776c07,
6568 fidl::encoding::DynamicFlags::empty(),
6569 )
6570 }
6571}
6572
6573#[must_use = "FIDL methods require a response to be sent"]
6574#[derive(Debug)]
6575pub struct BufferCollectionTokenDuplicateSyncResponder {
6576 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6577 tx_id: u32,
6578}
6579
6580/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6581/// if the responder is dropped without sending a response, so that the client
6582/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6583impl std::ops::Drop for BufferCollectionTokenDuplicateSyncResponder {
6584 fn drop(&mut self) {
6585 self.control_handle.shutdown();
6586 // Safety: drops once, never accessed again
6587 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6588 }
6589}
6590
6591impl fidl::endpoints::Responder for BufferCollectionTokenDuplicateSyncResponder {
6592 type ControlHandle = BufferCollectionTokenControlHandle;
6593
6594 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6595 &self.control_handle
6596 }
6597
6598 fn drop_without_shutdown(mut self) {
6599 // Safety: drops once, never accessed again due to mem::forget
6600 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6601 // Prevent Drop from running (which would shut down the channel)
6602 std::mem::forget(self);
6603 }
6604}
6605
6606impl BufferCollectionTokenDuplicateSyncResponder {
6607 /// Sends a response to the FIDL transaction.
6608 ///
6609 /// Sets the channel to shutdown if an error occurs.
6610 pub fn send(
6611 self,
6612 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6613 ) -> Result<(), fidl::Error> {
6614 let _result = self.send_raw(tokens);
6615 if _result.is_err() {
6616 self.control_handle.shutdown();
6617 }
6618 self.drop_without_shutdown();
6619 _result
6620 }
6621
6622 /// Similar to "send" but does not shutdown the channel if an error occurs.
6623 pub fn send_no_shutdown_on_err(
6624 self,
6625 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6626 ) -> Result<(), fidl::Error> {
6627 let _result = self.send_raw(tokens);
6628 self.drop_without_shutdown();
6629 _result
6630 }
6631
6632 fn send_raw(
6633 &self,
6634 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6635 ) -> Result<(), fidl::Error> {
6636 self.control_handle.inner.send::<BufferCollectionTokenDuplicateSyncResponse>(
6637 (tokens.as_mut(),),
6638 self.tx_id,
6639 0x49ed7ab7cc19f18,
6640 fidl::encoding::DynamicFlags::empty(),
6641 )
6642 }
6643}
6644
6645#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
6646pub struct BufferCollectionTokenGroupMarker;
6647
6648impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenGroupMarker {
6649 type Proxy = BufferCollectionTokenGroupProxy;
6650 type RequestStream = BufferCollectionTokenGroupRequestStream;
6651 #[cfg(target_os = "fuchsia")]
6652 type SynchronousProxy = BufferCollectionTokenGroupSynchronousProxy;
6653
6654 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionTokenGroup";
6655}
6656
6657pub trait BufferCollectionTokenGroupProxyInterface: Send + Sync {
6658 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
6659 fn r#sync(&self) -> Self::SyncResponseFut;
6660 fn r#close(&self) -> Result<(), fidl::Error>;
6661 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
6662 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
6663 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
6664 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
6665 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
6666 + Send;
6667 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
6668 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
6669 + Send;
6670 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
6671 fn r#create_child(
6672 &self,
6673 payload: BufferCollectionTokenGroupCreateChildRequest,
6674 ) -> Result<(), fidl::Error>;
6675 type CreateChildrenSyncResponseFut: std::future::Future<
6676 Output = Result<
6677 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6678 fidl::Error,
6679 >,
6680 > + Send;
6681 fn r#create_children_sync(
6682 &self,
6683 rights_attenuation_masks: &[fidl::Rights],
6684 ) -> Self::CreateChildrenSyncResponseFut;
6685 fn r#all_children_present(&self) -> Result<(), fidl::Error>;
6686}
6687#[derive(Debug)]
6688#[cfg(target_os = "fuchsia")]
6689pub struct BufferCollectionTokenGroupSynchronousProxy {
6690 client: fidl::client::sync::Client,
6691}
6692
6693#[cfg(target_os = "fuchsia")]
6694impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenGroupSynchronousProxy {
6695 type Proxy = BufferCollectionTokenGroupProxy;
6696 type Protocol = BufferCollectionTokenGroupMarker;
6697
6698 fn from_channel(inner: fidl::Channel) -> Self {
6699 Self::new(inner)
6700 }
6701
6702 fn into_channel(self) -> fidl::Channel {
6703 self.client.into_channel()
6704 }
6705
6706 fn as_channel(&self) -> &fidl::Channel {
6707 self.client.as_channel()
6708 }
6709}
6710
6711#[cfg(target_os = "fuchsia")]
6712impl BufferCollectionTokenGroupSynchronousProxy {
6713 pub fn new(channel: fidl::Channel) -> Self {
6714 let protocol_name =
6715 <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
6716 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
6717 }
6718
6719 pub fn into_channel(self) -> fidl::Channel {
6720 self.client.into_channel()
6721 }
6722
6723 /// Waits until an event arrives and returns it. It is safe for other
6724 /// threads to make concurrent requests while waiting for an event.
6725 pub fn wait_for_event(
6726 &self,
6727 deadline: zx::MonotonicInstant,
6728 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
6729 BufferCollectionTokenGroupEvent::decode(self.client.wait_for_event(deadline)?)
6730 }
6731
6732 /// Ensure that previous messages, including Duplicate() messages on a
6733 /// token, collection, or group, have been received server side.
6734 ///
6735 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
6736 /// valid sysmem token risks the Sync() hanging forever. See
6737 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
6738 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
6739 /// Another way is to pass the token to BindSharedCollection(), which also
6740 /// validates the token as part of exchanging it for a BufferCollection
6741 /// channel, and BufferCollection Sync() can then be used.
6742 ///
6743 /// After a Sync(), it's then safe to send the client end of token_request
6744 /// to another participant knowing the server will recognize the token when
6745 /// it's sent into BindSharedCollection() by the other participant.
6746 ///
6747 /// Other options include waiting for each token.Duplicate() to complete
6748 /// individually (using separate call to token.Sync() after each), or
6749 /// calling Sync() on BufferCollection after the token has been turned in
6750 /// via BindSharedCollection().
6751 ///
6752 /// Another way to mitigate is to avoid calling Sync() on the token, and
6753 /// instead later deal with potential failure of BufferCollection.Sync() if
6754 /// the original token was invalid. This option can be preferable from a
6755 /// performance point of view, but requires client code to delay sending
6756 /// tokens duplicated from this token until after client code has converted
6757 /// the duplicating token to a BufferCollection and received successful
6758 /// response from BufferCollection.Sync().
6759 ///
6760 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
6761 /// When BufferCollection.Sync() isn't feasible, the caller must already
6762 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
6763 /// hang forever. See ValidateBufferCollectionToken() to check token
6764 /// validity first if the token isn't already known to be (is/was) valid.
6765 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
6766 let _response =
6767 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
6768 (),
6769 0x4577e238ae26291,
6770 fidl::encoding::DynamicFlags::empty(),
6771 ___deadline,
6772 )?;
6773 Ok(_response)
6774 }
6775
6776 /// On a BufferCollectionToken channel:
6777 ///
6778 /// Normally a participant will convert a BufferCollectionToken into a
6779 /// BufferCollection view, but a participant is also free to Close() the
6780 /// token (and then close the channel immediately or shortly later in
6781 /// response to server closing its end), which avoids causing logical buffer
6782 /// collection failure. Â Normally an unexpected token channel close will
6783 /// cause logical buffer collection failure (the only exceptions being
6784 /// certain cases involving AttachToken() or SetDispensable()).
6785 ///
6786 /// On a BufferCollection channel:
6787 ///
6788 /// By default the server handles unexpected failure of a BufferCollection
6789 /// by failing the whole logical buffer collection. Partly this is to
6790 /// expedite closing VMO handles to reclaim memory when any participant
6791 /// fails. If a participant would like to cleanly close a BufferCollection
6792 /// view without causing logical buffer collection failure, the participant
6793 /// can send Close() before closing the client end of the BufferCollection
6794 /// channel. If this is the last BufferCollection view, the logical buffer
6795 /// collection will still go away. The Close() can occur before or after
6796 /// SetConstraints(). If before SetConstraints(), the buffer collection
6797 /// won't require constraints from this node in order to allocate. If
6798 /// after SetConstraints(), the constraints are retained and aggregated
6799 /// along with any subsequent logical allocation(s), despite the lack of
6800 /// channel connection.
6801 ///
6802 /// On a BufferCollectionTokenGroup channel:
6803 ///
6804 /// By default, unexpected failure of a BufferCollectionTokenGroup will
6805 /// trigger failure of the logical BufferCollectionTokenGroup and will
6806 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
6807 /// channel without failing the logical group or propagating failure, send
6808 /// Close() before closing the channel client endpoint.
6809 ///
6810 /// If Close() occurs before AllChildrenPresent(), the logical buffer
6811 /// collection will still fail despite the Close() (because sysmem can't be
6812 /// sure whether all relevant children were created, so it's ambiguous
6813 /// whether all relevant constraints will be provided to sysmem). If
6814 /// Close() occurs after AllChildrenPresent(), the children and all their
6815 /// constraints remain intact (just as they would if the
6816 /// BufferCollectionTokenGroup channel had remained open), and the close
6817 /// doesn't trigger or propagate failure.
6818 pub fn r#close(&self) -> Result<(), fidl::Error> {
6819 self.client.send::<fidl::encoding::EmptyPayload>(
6820 (),
6821 0x5b1d7a4f5681fca7,
6822 fidl::encoding::DynamicFlags::empty(),
6823 )
6824 }
6825
6826 /// Set a name for VMOs in this buffer collection. The name may be truncated
6827 /// shorter. The name only affects VMOs allocated after it's set - this call
6828 /// does not rename existing VMOs. If multiple clients set different names
6829 /// then the larger priority value will win.
6830 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
6831 self.client.send::<NodeSetNameRequest>(
6832 (priority, name),
6833 0x77a41bb6217e2443,
6834 fidl::encoding::DynamicFlags::empty(),
6835 )
6836 }
6837
6838 /// Set information about the current client that can be used by sysmem to
6839 /// help debug leaking memory and hangs waiting for constraints. |name| can
6840 /// be an arbitrary string, but the current process name (see
6841 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
6842 /// arbitrary id, but the current process ID (see
6843 /// fsl::GetCurrentProcessKoid()) is a good default.
6844 ///
6845 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
6846 /// indicate which client is closing their channel first, leading to
6847 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
6848 /// over, but if happening earlier than expected, the
6849 /// client-channel-specific name can help diagnose where the failure is
6850 /// first coming from, from sysmem's point of view).
6851 ///
6852 /// By default (unless overriden by this message or using
6853 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
6854 /// parent Node at the time the child Node is created. While this can be
6855 /// better than nothing, it's often better for each participant to use
6856 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
6857 /// info directly relevant to the current client. Also, SetVerboseLogging()
6858 /// can be used to help disambiguate if a Node is suspected of having info
6859 /// that was copied from its parent.
6860 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
6861 self.client.send::<NodeSetDebugClientInfoRequest>(
6862 (name, id),
6863 0x7275759070eb5ee2,
6864 fidl::encoding::DynamicFlags::empty(),
6865 )
6866 }
6867
6868 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
6869 /// after creating a collection. Clients can call this method to change
6870 /// when the log is printed. If multiple client set the deadline, it's
6871 /// unspecified which deadline will take effect.
6872 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
6873 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
6874 (deadline,),
6875 0x46d38f4772638867,
6876 fidl::encoding::DynamicFlags::empty(),
6877 )
6878 }
6879
6880 /// Verbose logging includes constraints set via SetConstraints() from each
6881 /// client along with info set via SetDebugClientInfo() and the structure of
6882 /// the tree of Node(s).
6883 ///
6884 /// Normally sysmem prints only a single line complaint when aggregation
6885 /// fails, with just the specific detailed reason that aggregation failed,
6886 /// with minimal context. While this is often enough to diagnose a problem
6887 /// if only a small change was made and the system had been working before
6888 /// the small change, it's often not particularly helpful for getting a new
6889 /// buffer collection to work for the first time. Especially with more
6890 /// complex trees of nodes, involving things like AttachToken(),
6891 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
6892 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
6893 /// looks like and why it's failing a logical allocation, or why a tree or
6894 /// sub-tree is failing sooner than expected.
6895 ///
6896 /// The intent of the extra logging is to be acceptable from a performance
6897 /// point of view, if only enabled on a low number of buffer collections.
6898 /// If we're not tracking down a bug, we shouldn't send this message.
6899 ///
6900 /// If too many participants leave verbose logging enabled, we may end up
6901 /// needing to require that system-wide sysmem verbose logging be permitted
6902 /// via some other setting, to avoid sysmem spamming the log too much due to
6903 /// this message.
6904 ///
6905 /// This may be a NOP for some nodes due to intentional policy associated
6906 /// with the node, if we don't trust a node enough to let it turn on verbose
6907 /// logging.
6908 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
6909 self.client.send::<fidl::encoding::EmptyPayload>(
6910 (),
6911 0x6bfbe2cf1701d288,
6912 fidl::encoding::DynamicFlags::empty(),
6913 )
6914 }
6915
6916 /// This gets an event handle that can be used as a parameter to
6917 /// IsAlternateFor() called on any Node. The client will not be granted the
6918 /// right to signal this event, as this handle should only be used as proof
6919 /// that the client obtained this handle from this Node.
6920 ///
6921 /// Because this is a get not a set, no Sync() is needed between the
6922 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
6923 /// potentially being on different channels.
6924 ///
6925 /// See also IsAlternateFor().
6926 pub fn r#get_node_ref(
6927 &self,
6928 ___deadline: zx::MonotonicInstant,
6929 ) -> Result<fidl::Event, fidl::Error> {
6930 let _response =
6931 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
6932 (),
6933 0x467b7c75c35c3b84,
6934 fidl::encoding::DynamicFlags::empty(),
6935 ___deadline,
6936 )?;
6937 Ok(_response.node_ref)
6938 }
6939
6940 /// This checks whether the calling node is in a subtree rooted at a
6941 /// different child token of a common parent BufferCollectionTokenGroup, in
6942 /// relation to the passed-in node_ref.
6943 ///
6944 /// This call is for assisting with admission control de-duplication, and
6945 /// with debugging.
6946 ///
6947 /// The node_ref must be obtained using GetNodeRef() of a
6948 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
6949 ///
6950 /// The node_ref can be a duplicated handle; it's not necessary to call
6951 /// GetNodeRef() for every call to IsAlternateFor().
6952 ///
6953 /// If a calling token may not actually be a valid token at all due to
6954 /// a potentially hostile/untrusted provider of the token, call
6955 /// ValidateBufferCollectionToken() first instead of potentially getting
6956 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
6957 /// token not being a real token (not really talking to sysmem). Another
6958 /// option is to call BindSharedCollection with this token first which also
6959 /// validates the token along with converting it to a BufferCollection, then
6960 /// call BufferCollection IsAlternateFor().
6961 ///
6962 /// error values:
6963 ///
6964 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
6965 /// buffer collection as the calling Node. Before logical allocation and
6966 /// within the same logical allocation sub-tree, this essentially means that
6967 /// the node_ref was never part of this logical buffer collection, since
6968 /// before logical allocation all node_refs that come into existence remain
6969 /// in existence at least until logical allocation (including Node(s) that
6970 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
6971 /// to be returned, this Node's channel needs to still be connected server
6972 /// side, which won't be the case if the whole logical allocation has
6973 /// failed. After logical allocation or in a different logical allocation
6974 /// sub-tree there are additional potential reasons for this error. For
6975 /// example a different logical allocation (separated from this Node(s)
6976 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
6977 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
6978 /// exist and may select a different child sub-tree than the sub-tree the
6979 /// node_ref is in causing deletion of the node_ref Node. The only time
6980 /// sysmem keeps a Node around after that Node has no corresponding channel
6981 /// is when Close() is used and the Node's sub-tree has not yet failed.
6982 /// Another reason for this error is if the node_ref is an eventpair handle
6983 /// with sufficient rights, but isn't actually a real node_ref obtained from
6984 /// GetNodeRef().
6985 ///
6986 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
6987 /// eventpair handle, or doesn't have the needed rights expected on a real
6988 /// node_ref.
6989 ///
6990 /// No other failing status codes are returned by this call. However,
6991 /// sysmem may add additional codes in future, so the client should have
6992 /// sensible default handling for any failing status code.
6993 ///
6994 /// On success, is_alternate has the following meaning:
6995 /// * true - The first parent node in common between the calling node and
6996 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
6997 /// the calling Node and the node_ref Node will _not_ have both their
6998 /// constraints apply - rather sysmem will choose one or the other of
6999 /// the constraints - never both. This is because only one child of
7000 /// a BufferCollectionTokenGroup is selected during logical allocation,
7001 /// with only that one child's sub-tree contributing to constraints
7002 /// aggregation.
7003 /// * false - The first parent node in common between the calling Node and
7004 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
7005 /// this means the first parent node in common is a
7006 /// BufferCollectionToken or BufferCollection (regardless of not
7007 /// Close()ed or Close()ed). This means that the calling Node and the
7008 /// node_ref Node _may_ have both their constraints apply during
7009 /// constraints aggregation of the logical allocation, if both Node(s)
7010 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
7011 /// In this case, there is no BufferCollectionTokenGroup that will
7012 /// directly prevent the two Node(s) from both being selected and their
7013 /// constraints both aggregated, but even when false, one or both
7014 /// Node(s) may still be eliminated from consideration if one or both
7015 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
7016 /// which selects a child sub-tree other than the sub-tree containing
7017 /// the calling Node or node_ref Node.
7018 pub fn r#is_alternate_for(
7019 &self,
7020 mut node_ref: fidl::Event,
7021 ___deadline: zx::MonotonicInstant,
7022 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
7023 let _response = self.client.send_query::<
7024 NodeIsAlternateForRequest,
7025 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
7026 >(
7027 (node_ref,),
7028 0x33a2a7aff2776c07,
7029 fidl::encoding::DynamicFlags::empty(),
7030 ___deadline,
7031 )?;
7032 Ok(_response.map(|x| x.is_alternate))
7033 }
7034
7035 /// Create a child token. Before passing the client end of this token to
7036 /// BindSharedCollection(), completion of Sync() after CreateChild() is
7037 /// required. Or the client can use CreateChildrenSync() which essentially
7038 /// includes the Sync().
7039 ///
7040 /// token_request - the server end of the new token channel.
7041 ///
7042 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
7043 /// allows the holder to get the same rights to buffers as the parent token
7044 /// (of the group) had.
7045 pub fn r#create_child(
7046 &self,
7047 mut payload: BufferCollectionTokenGroupCreateChildRequest,
7048 ) -> Result<(), fidl::Error> {
7049 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
7050 &mut payload,
7051 0x2e74f8bcbf59ee59,
7052 fidl::encoding::DynamicFlags::empty(),
7053 )
7054 }
7055
7056 /// Create 1 or more child tokens at once, synchronously. In contrast to
7057 /// CreateChild(), no Sync() completion is required before passing the
7058 /// client end of a returned token to BindSharedCollection().
7059 ///
7060 /// The size of the rights_attentuation_mask determines the number of
7061 /// created child tokens.
7062 ///
7063 /// The lower-index child tokens are higher priority (attempted sooner) than
7064 /// higher-index child tokens.
7065 ///
7066 /// As per all child tokens, successful aggregation will choose exactly one
7067 /// child among all created children (across all children created across
7068 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
7069 ///
7070 /// The maximum permissible total number of children per group, and total
7071 /// number of nodes in an overall tree (from the root) are capped to limits
7072 /// which are not configurable via these protocols.
7073 pub fn r#create_children_sync(
7074 &self,
7075 mut rights_attenuation_masks: &[fidl::Rights],
7076 ___deadline: zx::MonotonicInstant,
7077 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error> {
7078 let _response = self.client.send_query::<
7079 BufferCollectionTokenGroupCreateChildrenSyncRequest,
7080 BufferCollectionTokenGroupCreateChildrenSyncResponse,
7081 >(
7082 (rights_attenuation_masks,),
7083 0x569dc3ca2a98f535,
7084 fidl::encoding::DynamicFlags::empty(),
7085 ___deadline,
7086 )?;
7087 Ok(_response.tokens)
7088 }
7089
7090 /// AllChildrenPresent()
7091 ///
7092 /// After creating all children, the client must call AllChildrenPresent()
7093 /// to inform sysmem that no more children will be created, so that sysmem
7094 /// can know when it's ok to start aggregating constraints.
7095 ///
7096 /// If Close() is to be sent, it should be sent _after_
7097 /// AllChildrenPresent(), else failure of the group and propagation of the
7098 /// failure to the group's parent will still be triggered.
7099 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
7100 self.client.send::<fidl::encoding::EmptyPayload>(
7101 (),
7102 0x1d41715f6f044b50,
7103 fidl::encoding::DynamicFlags::empty(),
7104 )
7105 }
7106}
7107
7108#[derive(Debug, Clone)]
7109pub struct BufferCollectionTokenGroupProxy {
7110 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
7111}
7112
7113impl fidl::endpoints::Proxy for BufferCollectionTokenGroupProxy {
7114 type Protocol = BufferCollectionTokenGroupMarker;
7115
7116 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
7117 Self::new(inner)
7118 }
7119
7120 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
7121 self.client.into_channel().map_err(|client| Self { client })
7122 }
7123
7124 fn as_channel(&self) -> &::fidl::AsyncChannel {
7125 self.client.as_channel()
7126 }
7127}
7128
7129impl BufferCollectionTokenGroupProxy {
7130 /// Create a new Proxy for fuchsia.sysmem/BufferCollectionTokenGroup.
7131 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
7132 let protocol_name =
7133 <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
7134 Self { client: fidl::client::Client::new(channel, protocol_name) }
7135 }
7136
7137 /// Get a Stream of events from the remote end of the protocol.
7138 ///
7139 /// # Panics
7140 ///
7141 /// Panics if the event stream was already taken.
7142 pub fn take_event_stream(&self) -> BufferCollectionTokenGroupEventStream {
7143 BufferCollectionTokenGroupEventStream { event_receiver: self.client.take_event_receiver() }
7144 }
7145
7146 /// Ensure that previous messages, including Duplicate() messages on a
7147 /// token, collection, or group, have been received server side.
7148 ///
7149 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
7150 /// valid sysmem token risks the Sync() hanging forever. See
7151 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
7152 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
7153 /// Another way is to pass the token to BindSharedCollection(), which also
7154 /// validates the token as part of exchanging it for a BufferCollection
7155 /// channel, and BufferCollection Sync() can then be used.
7156 ///
7157 /// After a Sync(), it's then safe to send the client end of token_request
7158 /// to another participant knowing the server will recognize the token when
7159 /// it's sent into BindSharedCollection() by the other participant.
7160 ///
7161 /// Other options include waiting for each token.Duplicate() to complete
7162 /// individually (using separate call to token.Sync() after each), or
7163 /// calling Sync() on BufferCollection after the token has been turned in
7164 /// via BindSharedCollection().
7165 ///
7166 /// Another way to mitigate is to avoid calling Sync() on the token, and
7167 /// instead later deal with potential failure of BufferCollection.Sync() if
7168 /// the original token was invalid. This option can be preferable from a
7169 /// performance point of view, but requires client code to delay sending
7170 /// tokens duplicated from this token until after client code has converted
7171 /// the duplicating token to a BufferCollection and received successful
7172 /// response from BufferCollection.Sync().
7173 ///
7174 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
7175 /// When BufferCollection.Sync() isn't feasible, the caller must already
7176 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
7177 /// hang forever. See ValidateBufferCollectionToken() to check token
7178 /// validity first if the token isn't already known to be (is/was) valid.
7179 pub fn r#sync(
7180 &self,
7181 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
7182 BufferCollectionTokenGroupProxyInterface::r#sync(self)
7183 }
7184
7185 /// On a BufferCollectionToken channel:
7186 ///
7187 /// Normally a participant will convert a BufferCollectionToken into a
7188 /// BufferCollection view, but a participant is also free to Close() the
7189 /// token (and then close the channel immediately or shortly later in
7190 /// response to server closing its end), which avoids causing logical buffer
7191 /// collection failure. Â Normally an unexpected token channel close will
7192 /// cause logical buffer collection failure (the only exceptions being
7193 /// certain cases involving AttachToken() or SetDispensable()).
7194 ///
7195 /// On a BufferCollection channel:
7196 ///
7197 /// By default the server handles unexpected failure of a BufferCollection
7198 /// by failing the whole logical buffer collection. Partly this is to
7199 /// expedite closing VMO handles to reclaim memory when any participant
7200 /// fails. If a participant would like to cleanly close a BufferCollection
7201 /// view without causing logical buffer collection failure, the participant
7202 /// can send Close() before closing the client end of the BufferCollection
7203 /// channel. If this is the last BufferCollection view, the logical buffer
7204 /// collection will still go away. The Close() can occur before or after
7205 /// SetConstraints(). If before SetConstraints(), the buffer collection
7206 /// won't require constraints from this node in order to allocate. If
7207 /// after SetConstraints(), the constraints are retained and aggregated
7208 /// along with any subsequent logical allocation(s), despite the lack of
7209 /// channel connection.
7210 ///
7211 /// On a BufferCollectionTokenGroup channel:
7212 ///
7213 /// By default, unexpected failure of a BufferCollectionTokenGroup will
7214 /// trigger failure of the logical BufferCollectionTokenGroup and will
7215 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
7216 /// channel without failing the logical group or propagating failure, send
7217 /// Close() before closing the channel client endpoint.
7218 ///
7219 /// If Close() occurs before AllChildrenPresent(), the logical buffer
7220 /// collection will still fail despite the Close() (because sysmem can't be
7221 /// sure whether all relevant children were created, so it's ambiguous
7222 /// whether all relevant constraints will be provided to sysmem). If
7223 /// Close() occurs after AllChildrenPresent(), the children and all their
7224 /// constraints remain intact (just as they would if the
7225 /// BufferCollectionTokenGroup channel had remained open), and the close
7226 /// doesn't trigger or propagate failure.
7227 pub fn r#close(&self) -> Result<(), fidl::Error> {
7228 BufferCollectionTokenGroupProxyInterface::r#close(self)
7229 }
7230
7231 /// Set a name for VMOs in this buffer collection. The name may be truncated
7232 /// shorter. The name only affects VMOs allocated after it's set - this call
7233 /// does not rename existing VMOs. If multiple clients set different names
7234 /// then the larger priority value will win.
7235 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
7236 BufferCollectionTokenGroupProxyInterface::r#set_name(self, priority, name)
7237 }
7238
7239 /// Set information about the current client that can be used by sysmem to
7240 /// help debug leaking memory and hangs waiting for constraints. |name| can
7241 /// be an arbitrary string, but the current process name (see
7242 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
7243 /// arbitrary id, but the current process ID (see
7244 /// fsl::GetCurrentProcessKoid()) is a good default.
7245 ///
7246 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
7247 /// indicate which client is closing their channel first, leading to
7248 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
7249 /// over, but if happening earlier than expected, the
7250 /// client-channel-specific name can help diagnose where the failure is
7251 /// first coming from, from sysmem's point of view).
7252 ///
7253 /// By default (unless overriden by this message or using
7254 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
7255 /// parent Node at the time the child Node is created. While this can be
7256 /// better than nothing, it's often better for each participant to use
7257 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
7258 /// info directly relevant to the current client. Also, SetVerboseLogging()
7259 /// can be used to help disambiguate if a Node is suspected of having info
7260 /// that was copied from its parent.
7261 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
7262 BufferCollectionTokenGroupProxyInterface::r#set_debug_client_info(self, name, id)
7263 }
7264
7265 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
7266 /// after creating a collection. Clients can call this method to change
7267 /// when the log is printed. If multiple client set the deadline, it's
7268 /// unspecified which deadline will take effect.
7269 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
7270 BufferCollectionTokenGroupProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
7271 }
7272
7273 /// Verbose logging includes constraints set via SetConstraints() from each
7274 /// client along with info set via SetDebugClientInfo() and the structure of
7275 /// the tree of Node(s).
7276 ///
7277 /// Normally sysmem prints only a single line complaint when aggregation
7278 /// fails, with just the specific detailed reason that aggregation failed,
7279 /// with minimal context. While this is often enough to diagnose a problem
7280 /// if only a small change was made and the system had been working before
7281 /// the small change, it's often not particularly helpful for getting a new
7282 /// buffer collection to work for the first time. Especially with more
7283 /// complex trees of nodes, involving things like AttachToken(),
7284 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
7285 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
7286 /// looks like and why it's failing a logical allocation, or why a tree or
7287 /// sub-tree is failing sooner than expected.
7288 ///
7289 /// The intent of the extra logging is to be acceptable from a performance
7290 /// point of view, if only enabled on a low number of buffer collections.
7291 /// If we're not tracking down a bug, we shouldn't send this message.
7292 ///
7293 /// If too many participants leave verbose logging enabled, we may end up
7294 /// needing to require that system-wide sysmem verbose logging be permitted
7295 /// via some other setting, to avoid sysmem spamming the log too much due to
7296 /// this message.
7297 ///
7298 /// This may be a NOP for some nodes due to intentional policy associated
7299 /// with the node, if we don't trust a node enough to let it turn on verbose
7300 /// logging.
7301 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7302 BufferCollectionTokenGroupProxyInterface::r#set_verbose_logging(self)
7303 }
7304
7305 /// This gets an event handle that can be used as a parameter to
7306 /// IsAlternateFor() called on any Node. The client will not be granted the
7307 /// right to signal this event, as this handle should only be used as proof
7308 /// that the client obtained this handle from this Node.
7309 ///
7310 /// Because this is a get not a set, no Sync() is needed between the
7311 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
7312 /// potentially being on different channels.
7313 ///
7314 /// See also IsAlternateFor().
7315 pub fn r#get_node_ref(
7316 &self,
7317 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
7318 {
7319 BufferCollectionTokenGroupProxyInterface::r#get_node_ref(self)
7320 }
7321
7322 /// This checks whether the calling node is in a subtree rooted at a
7323 /// different child token of a common parent BufferCollectionTokenGroup, in
7324 /// relation to the passed-in node_ref.
7325 ///
7326 /// This call is for assisting with admission control de-duplication, and
7327 /// with debugging.
7328 ///
7329 /// The node_ref must be obtained using GetNodeRef() of a
7330 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
7331 ///
7332 /// The node_ref can be a duplicated handle; it's not necessary to call
7333 /// GetNodeRef() for every call to IsAlternateFor().
7334 ///
7335 /// If a calling token may not actually be a valid token at all due to
7336 /// a potentially hostile/untrusted provider of the token, call
7337 /// ValidateBufferCollectionToken() first instead of potentially getting
7338 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
7339 /// token not being a real token (not really talking to sysmem). Another
7340 /// option is to call BindSharedCollection with this token first which also
7341 /// validates the token along with converting it to a BufferCollection, then
7342 /// call BufferCollection IsAlternateFor().
7343 ///
7344 /// error values:
7345 ///
7346 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
7347 /// buffer collection as the calling Node. Before logical allocation and
7348 /// within the same logical allocation sub-tree, this essentially means that
7349 /// the node_ref was never part of this logical buffer collection, since
7350 /// before logical allocation all node_refs that come into existence remain
7351 /// in existence at least until logical allocation (including Node(s) that
7352 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
7353 /// to be returned, this Node's channel needs to still be connected server
7354 /// side, which won't be the case if the whole logical allocation has
7355 /// failed. After logical allocation or in a different logical allocation
7356 /// sub-tree there are additional potential reasons for this error. For
7357 /// example a different logical allocation (separated from this Node(s)
7358 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
7359 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
7360 /// exist and may select a different child sub-tree than the sub-tree the
7361 /// node_ref is in causing deletion of the node_ref Node. The only time
7362 /// sysmem keeps a Node around after that Node has no corresponding channel
7363 /// is when Close() is used and the Node's sub-tree has not yet failed.
7364 /// Another reason for this error is if the node_ref is an eventpair handle
7365 /// with sufficient rights, but isn't actually a real node_ref obtained from
7366 /// GetNodeRef().
7367 ///
7368 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
7369 /// eventpair handle, or doesn't have the needed rights expected on a real
7370 /// node_ref.
7371 ///
7372 /// No other failing status codes are returned by this call. However,
7373 /// sysmem may add additional codes in future, so the client should have
7374 /// sensible default handling for any failing status code.
7375 ///
7376 /// On success, is_alternate has the following meaning:
7377 /// * true - The first parent node in common between the calling node and
7378 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
7379 /// the calling Node and the node_ref Node will _not_ have both their
7380 /// constraints apply - rather sysmem will choose one or the other of
7381 /// the constraints - never both. This is because only one child of
7382 /// a BufferCollectionTokenGroup is selected during logical allocation,
7383 /// with only that one child's sub-tree contributing to constraints
7384 /// aggregation.
7385 /// * false - The first parent node in common between the calling Node and
7386 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
7387 /// this means the first parent node in common is a
7388 /// BufferCollectionToken or BufferCollection (regardless of not
7389 /// Close()ed or Close()ed). This means that the calling Node and the
7390 /// node_ref Node _may_ have both their constraints apply during
7391 /// constraints aggregation of the logical allocation, if both Node(s)
7392 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
7393 /// In this case, there is no BufferCollectionTokenGroup that will
7394 /// directly prevent the two Node(s) from both being selected and their
7395 /// constraints both aggregated, but even when false, one or both
7396 /// Node(s) may still be eliminated from consideration if one or both
7397 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
7398 /// which selects a child sub-tree other than the sub-tree containing
7399 /// the calling Node or node_ref Node.
7400 pub fn r#is_alternate_for(
7401 &self,
7402 mut node_ref: fidl::Event,
7403 ) -> fidl::client::QueryResponseFut<
7404 NodeIsAlternateForResult,
7405 fidl::encoding::DefaultFuchsiaResourceDialect,
7406 > {
7407 BufferCollectionTokenGroupProxyInterface::r#is_alternate_for(self, node_ref)
7408 }
7409
7410 /// Create a child token. Before passing the client end of this token to
7411 /// BindSharedCollection(), completion of Sync() after CreateChild() is
7412 /// required. Or the client can use CreateChildrenSync() which essentially
7413 /// includes the Sync().
7414 ///
7415 /// token_request - the server end of the new token channel.
7416 ///
7417 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
7418 /// allows the holder to get the same rights to buffers as the parent token
7419 /// (of the group) had.
7420 pub fn r#create_child(
7421 &self,
7422 mut payload: BufferCollectionTokenGroupCreateChildRequest,
7423 ) -> Result<(), fidl::Error> {
7424 BufferCollectionTokenGroupProxyInterface::r#create_child(self, payload)
7425 }
7426
7427 /// Create 1 or more child tokens at once, synchronously. In contrast to
7428 /// CreateChild(), no Sync() completion is required before passing the
7429 /// client end of a returned token to BindSharedCollection().
7430 ///
7431 /// The size of the rights_attentuation_mask determines the number of
7432 /// created child tokens.
7433 ///
7434 /// The lower-index child tokens are higher priority (attempted sooner) than
7435 /// higher-index child tokens.
7436 ///
7437 /// As per all child tokens, successful aggregation will choose exactly one
7438 /// child among all created children (across all children created across
7439 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
7440 ///
7441 /// The maximum permissible total number of children per group, and total
7442 /// number of nodes in an overall tree (from the root) are capped to limits
7443 /// which are not configurable via these protocols.
7444 pub fn r#create_children_sync(
7445 &self,
7446 mut rights_attenuation_masks: &[fidl::Rights],
7447 ) -> fidl::client::QueryResponseFut<
7448 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7449 fidl::encoding::DefaultFuchsiaResourceDialect,
7450 > {
7451 BufferCollectionTokenGroupProxyInterface::r#create_children_sync(
7452 self,
7453 rights_attenuation_masks,
7454 )
7455 }
7456
7457 /// AllChildrenPresent()
7458 ///
7459 /// After creating all children, the client must call AllChildrenPresent()
7460 /// to inform sysmem that no more children will be created, so that sysmem
7461 /// can know when it's ok to start aggregating constraints.
7462 ///
7463 /// If Close() is to be sent, it should be sent _after_
7464 /// AllChildrenPresent(), else failure of the group and propagation of the
7465 /// failure to the group's parent will still be triggered.
7466 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
7467 BufferCollectionTokenGroupProxyInterface::r#all_children_present(self)
7468 }
7469}
7470
7471impl BufferCollectionTokenGroupProxyInterface for BufferCollectionTokenGroupProxy {
7472 type SyncResponseFut =
7473 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
7474 fn r#sync(&self) -> Self::SyncResponseFut {
7475 fn _decode(
7476 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7477 ) -> Result<(), fidl::Error> {
7478 let _response = fidl::client::decode_transaction_body::<
7479 fidl::encoding::EmptyPayload,
7480 fidl::encoding::DefaultFuchsiaResourceDialect,
7481 0x4577e238ae26291,
7482 >(_buf?)?;
7483 Ok(_response)
7484 }
7485 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
7486 (),
7487 0x4577e238ae26291,
7488 fidl::encoding::DynamicFlags::empty(),
7489 _decode,
7490 )
7491 }
7492
7493 fn r#close(&self) -> Result<(), fidl::Error> {
7494 self.client.send::<fidl::encoding::EmptyPayload>(
7495 (),
7496 0x5b1d7a4f5681fca7,
7497 fidl::encoding::DynamicFlags::empty(),
7498 )
7499 }
7500
7501 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
7502 self.client.send::<NodeSetNameRequest>(
7503 (priority, name),
7504 0x77a41bb6217e2443,
7505 fidl::encoding::DynamicFlags::empty(),
7506 )
7507 }
7508
7509 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
7510 self.client.send::<NodeSetDebugClientInfoRequest>(
7511 (name, id),
7512 0x7275759070eb5ee2,
7513 fidl::encoding::DynamicFlags::empty(),
7514 )
7515 }
7516
7517 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
7518 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
7519 (deadline,),
7520 0x46d38f4772638867,
7521 fidl::encoding::DynamicFlags::empty(),
7522 )
7523 }
7524
7525 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7526 self.client.send::<fidl::encoding::EmptyPayload>(
7527 (),
7528 0x6bfbe2cf1701d288,
7529 fidl::encoding::DynamicFlags::empty(),
7530 )
7531 }
7532
7533 type GetNodeRefResponseFut =
7534 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
7535 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
7536 fn _decode(
7537 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7538 ) -> Result<fidl::Event, fidl::Error> {
7539 let _response = fidl::client::decode_transaction_body::<
7540 NodeGetNodeRefResponse,
7541 fidl::encoding::DefaultFuchsiaResourceDialect,
7542 0x467b7c75c35c3b84,
7543 >(_buf?)?;
7544 Ok(_response.node_ref)
7545 }
7546 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
7547 (),
7548 0x467b7c75c35c3b84,
7549 fidl::encoding::DynamicFlags::empty(),
7550 _decode,
7551 )
7552 }
7553
7554 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
7555 NodeIsAlternateForResult,
7556 fidl::encoding::DefaultFuchsiaResourceDialect,
7557 >;
7558 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
7559 fn _decode(
7560 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7561 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
7562 let _response = fidl::client::decode_transaction_body::<
7563 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
7564 fidl::encoding::DefaultFuchsiaResourceDialect,
7565 0x33a2a7aff2776c07,
7566 >(_buf?)?;
7567 Ok(_response.map(|x| x.is_alternate))
7568 }
7569 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
7570 (node_ref,),
7571 0x33a2a7aff2776c07,
7572 fidl::encoding::DynamicFlags::empty(),
7573 _decode,
7574 )
7575 }
7576
7577 fn r#create_child(
7578 &self,
7579 mut payload: BufferCollectionTokenGroupCreateChildRequest,
7580 ) -> Result<(), fidl::Error> {
7581 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
7582 &mut payload,
7583 0x2e74f8bcbf59ee59,
7584 fidl::encoding::DynamicFlags::empty(),
7585 )
7586 }
7587
7588 type CreateChildrenSyncResponseFut = fidl::client::QueryResponseFut<
7589 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7590 fidl::encoding::DefaultFuchsiaResourceDialect,
7591 >;
7592 fn r#create_children_sync(
7593 &self,
7594 mut rights_attenuation_masks: &[fidl::Rights],
7595 ) -> Self::CreateChildrenSyncResponseFut {
7596 fn _decode(
7597 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7598 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error>
7599 {
7600 let _response = fidl::client::decode_transaction_body::<
7601 BufferCollectionTokenGroupCreateChildrenSyncResponse,
7602 fidl::encoding::DefaultFuchsiaResourceDialect,
7603 0x569dc3ca2a98f535,
7604 >(_buf?)?;
7605 Ok(_response.tokens)
7606 }
7607 self.client.send_query_and_decode::<
7608 BufferCollectionTokenGroupCreateChildrenSyncRequest,
7609 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7610 >(
7611 (rights_attenuation_masks,),
7612 0x569dc3ca2a98f535,
7613 fidl::encoding::DynamicFlags::empty(),
7614 _decode,
7615 )
7616 }
7617
7618 fn r#all_children_present(&self) -> Result<(), fidl::Error> {
7619 self.client.send::<fidl::encoding::EmptyPayload>(
7620 (),
7621 0x1d41715f6f044b50,
7622 fidl::encoding::DynamicFlags::empty(),
7623 )
7624 }
7625}
7626
7627pub struct BufferCollectionTokenGroupEventStream {
7628 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
7629}
7630
7631impl std::marker::Unpin for BufferCollectionTokenGroupEventStream {}
7632
7633impl futures::stream::FusedStream for BufferCollectionTokenGroupEventStream {
7634 fn is_terminated(&self) -> bool {
7635 self.event_receiver.is_terminated()
7636 }
7637}
7638
7639impl futures::Stream for BufferCollectionTokenGroupEventStream {
7640 type Item = Result<BufferCollectionTokenGroupEvent, fidl::Error>;
7641
7642 fn poll_next(
7643 mut self: std::pin::Pin<&mut Self>,
7644 cx: &mut std::task::Context<'_>,
7645 ) -> std::task::Poll<Option<Self::Item>> {
7646 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
7647 &mut self.event_receiver,
7648 cx
7649 )?) {
7650 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenGroupEvent::decode(buf))),
7651 None => std::task::Poll::Ready(None),
7652 }
7653 }
7654}
7655
7656#[derive(Debug)]
7657pub enum BufferCollectionTokenGroupEvent {}
7658
7659impl BufferCollectionTokenGroupEvent {
7660 /// Decodes a message buffer as a [`BufferCollectionTokenGroupEvent`].
7661 fn decode(
7662 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
7663 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
7664 let (bytes, _handles) = buf.split_mut();
7665 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7666 debug_assert_eq!(tx_header.tx_id, 0);
7667 match tx_header.ordinal {
7668 _ => Err(fidl::Error::UnknownOrdinal {
7669 ordinal: tx_header.ordinal,
7670 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
7671 })
7672 }
7673 }
7674}
7675
7676/// A Stream of incoming requests for fuchsia.sysmem/BufferCollectionTokenGroup.
7677pub struct BufferCollectionTokenGroupRequestStream {
7678 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7679 is_terminated: bool,
7680}
7681
7682impl std::marker::Unpin for BufferCollectionTokenGroupRequestStream {}
7683
7684impl futures::stream::FusedStream for BufferCollectionTokenGroupRequestStream {
7685 fn is_terminated(&self) -> bool {
7686 self.is_terminated
7687 }
7688}
7689
7690impl fidl::endpoints::RequestStream for BufferCollectionTokenGroupRequestStream {
7691 type Protocol = BufferCollectionTokenGroupMarker;
7692 type ControlHandle = BufferCollectionTokenGroupControlHandle;
7693
7694 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
7695 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
7696 }
7697
7698 fn control_handle(&self) -> Self::ControlHandle {
7699 BufferCollectionTokenGroupControlHandle { inner: self.inner.clone() }
7700 }
7701
7702 fn into_inner(
7703 self,
7704 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
7705 {
7706 (self.inner, self.is_terminated)
7707 }
7708
7709 fn from_inner(
7710 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7711 is_terminated: bool,
7712 ) -> Self {
7713 Self { inner, is_terminated }
7714 }
7715}
7716
7717impl futures::Stream for BufferCollectionTokenGroupRequestStream {
7718 type Item = Result<BufferCollectionTokenGroupRequest, fidl::Error>;
7719
7720 fn poll_next(
7721 mut self: std::pin::Pin<&mut Self>,
7722 cx: &mut std::task::Context<'_>,
7723 ) -> std::task::Poll<Option<Self::Item>> {
7724 let this = &mut *self;
7725 if this.inner.check_shutdown(cx) {
7726 this.is_terminated = true;
7727 return std::task::Poll::Ready(None);
7728 }
7729 if this.is_terminated {
7730 panic!("polled BufferCollectionTokenGroupRequestStream after completion");
7731 }
7732 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
7733 |bytes, handles| {
7734 match this.inner.channel().read_etc(cx, bytes, handles) {
7735 std::task::Poll::Ready(Ok(())) => {}
7736 std::task::Poll::Pending => return std::task::Poll::Pending,
7737 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
7738 this.is_terminated = true;
7739 return std::task::Poll::Ready(None);
7740 }
7741 std::task::Poll::Ready(Err(e)) => {
7742 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
7743 e.into(),
7744 ))))
7745 }
7746 }
7747
7748 // A message has been received from the channel
7749 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7750
7751 std::task::Poll::Ready(Some(match header.ordinal {
7752 0x4577e238ae26291 => {
7753 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7754 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7755 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7756 let control_handle = BufferCollectionTokenGroupControlHandle {
7757 inner: this.inner.clone(),
7758 };
7759 Ok(BufferCollectionTokenGroupRequest::Sync {
7760 responder: BufferCollectionTokenGroupSyncResponder {
7761 control_handle: std::mem::ManuallyDrop::new(control_handle),
7762 tx_id: header.tx_id,
7763 },
7764 })
7765 }
7766 0x5b1d7a4f5681fca7 => {
7767 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7768 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7769 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7770 let control_handle = BufferCollectionTokenGroupControlHandle {
7771 inner: this.inner.clone(),
7772 };
7773 Ok(BufferCollectionTokenGroupRequest::Close {
7774 control_handle,
7775 })
7776 }
7777 0x77a41bb6217e2443 => {
7778 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7779 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7780 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
7781 let control_handle = BufferCollectionTokenGroupControlHandle {
7782 inner: this.inner.clone(),
7783 };
7784 Ok(BufferCollectionTokenGroupRequest::SetName {priority: req.priority,
7785name: req.name,
7786
7787 control_handle,
7788 })
7789 }
7790 0x7275759070eb5ee2 => {
7791 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7792 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7793 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
7794 let control_handle = BufferCollectionTokenGroupControlHandle {
7795 inner: this.inner.clone(),
7796 };
7797 Ok(BufferCollectionTokenGroupRequest::SetDebugClientInfo {name: req.name,
7798id: req.id,
7799
7800 control_handle,
7801 })
7802 }
7803 0x46d38f4772638867 => {
7804 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7805 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7806 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
7807 let control_handle = BufferCollectionTokenGroupControlHandle {
7808 inner: this.inner.clone(),
7809 };
7810 Ok(BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {deadline: req.deadline,
7811
7812 control_handle,
7813 })
7814 }
7815 0x6bfbe2cf1701d288 => {
7816 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7817 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7818 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7819 let control_handle = BufferCollectionTokenGroupControlHandle {
7820 inner: this.inner.clone(),
7821 };
7822 Ok(BufferCollectionTokenGroupRequest::SetVerboseLogging {
7823 control_handle,
7824 })
7825 }
7826 0x467b7c75c35c3b84 => {
7827 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7828 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7829 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7830 let control_handle = BufferCollectionTokenGroupControlHandle {
7831 inner: this.inner.clone(),
7832 };
7833 Ok(BufferCollectionTokenGroupRequest::GetNodeRef {
7834 responder: BufferCollectionTokenGroupGetNodeRefResponder {
7835 control_handle: std::mem::ManuallyDrop::new(control_handle),
7836 tx_id: header.tx_id,
7837 },
7838 })
7839 }
7840 0x33a2a7aff2776c07 => {
7841 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7842 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7843 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
7844 let control_handle = BufferCollectionTokenGroupControlHandle {
7845 inner: this.inner.clone(),
7846 };
7847 Ok(BufferCollectionTokenGroupRequest::IsAlternateFor {node_ref: req.node_ref,
7848
7849 responder: BufferCollectionTokenGroupIsAlternateForResponder {
7850 control_handle: std::mem::ManuallyDrop::new(control_handle),
7851 tx_id: header.tx_id,
7852 },
7853 })
7854 }
7855 0x2e74f8bcbf59ee59 => {
7856 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7857 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7858 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildRequest>(&header, _body_bytes, handles, &mut req)?;
7859 let control_handle = BufferCollectionTokenGroupControlHandle {
7860 inner: this.inner.clone(),
7861 };
7862 Ok(BufferCollectionTokenGroupRequest::CreateChild {payload: req,
7863 control_handle,
7864 })
7865 }
7866 0x569dc3ca2a98f535 => {
7867 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7868 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildrenSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7869 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildrenSyncRequest>(&header, _body_bytes, handles, &mut req)?;
7870 let control_handle = BufferCollectionTokenGroupControlHandle {
7871 inner: this.inner.clone(),
7872 };
7873 Ok(BufferCollectionTokenGroupRequest::CreateChildrenSync {rights_attenuation_masks: req.rights_attenuation_masks,
7874
7875 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder {
7876 control_handle: std::mem::ManuallyDrop::new(control_handle),
7877 tx_id: header.tx_id,
7878 },
7879 })
7880 }
7881 0x1d41715f6f044b50 => {
7882 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7883 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7884 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7885 let control_handle = BufferCollectionTokenGroupControlHandle {
7886 inner: this.inner.clone(),
7887 };
7888 Ok(BufferCollectionTokenGroupRequest::AllChildrenPresent {
7889 control_handle,
7890 })
7891 }
7892 _ => Err(fidl::Error::UnknownOrdinal {
7893 ordinal: header.ordinal,
7894 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
7895 }),
7896 }))
7897 },
7898 )
7899 }
7900}
7901
7902/// The sysmem implementation is guaranteed to be consistent with a logical /
7903/// conceptual model as follows:
7904///
7905/// As usual, a logical allocation considers either the root and all nodes with
7906/// connectivity to the root that don't transit an AttachToken(), or a sub-tree
7907/// rooted at an AttachToken() token and all nodes with connectivity to that
7908/// subtree that don't transit another AttachToken(). This is called the
7909/// logical allocation pruned sub-tree, or pruned sub-tree for short.
7910///
7911/// During constraints aggregation, each BufferCollectionTokenGroup will select
7912/// a single child token among its children. The rest of the children will
7913/// appear to fail the logical allocation, while the selected child may succeed.
7914///
7915/// When more than one BufferCollectionTokenGroup exists in the overall logical
7916/// allocation pruned sub-tree, the relative priority between two groups is
7917/// equivalent to their ordering in a DFS pre-order iteration of the tree, with
7918/// parents higher priority than children, and left children higher priority
7919/// than right children.
7920///
7921/// When a particular child of a group is selected (whether provisionally during
7922/// a constraints aggregation attempt, or as a final selection), the
7923/// non-selection of other children of the group can potentially "hide" other
7924/// groups under those non-selected children.
7925///
7926/// Within a logical allocation, aggregation is attempted first by provisionally
7927/// selecting the child 0 of the highest-priority group, and child 0 of the next
7928/// highest-priority group that isn't hidden by the provisional selections so
7929/// far, etc.
7930///
7931/// If that aggregation attempt fails, aggregation will be attempted with the
7932/// ordinal 0 child of all the same groups except the lowest priority non-hidden
7933/// group which will provisionally select its ordinal 1 child (and then child 2
7934/// and so on). If a new lowest-priority group is un-hidden as provisional
7935/// selections are updated, that newly un-hidden lowest-priority group has all
7936/// its children considered in order, before changing the provisional selection
7937/// in the former lowest-priority group. In terms of result, this is equivalent
7938/// to systematic enumeration of all possible combinations of choices in a
7939/// counting-like order updating the lowest-priority group the most often and
7940/// the highest-priority group the least often. Rather than actually attempting
7941/// aggregation with all the combinations, we can skip over combinations which
7942/// are redundant/equivalent due to hiding without any change to the result.
7943///
7944/// Attempted aggregations of enumerated non-equivalent combinations of choices
7945/// continue in this manner until either (a) all aggregation attempts fail in
7946/// which case the overall logical allocation fails, or (b) until an attempted
7947/// aggregation succeeds, in which case buffer allocation (if needed) is
7948/// attempted once. If buffer allocation based on the first successful
7949/// aggregation fails, the overall logical allocation fails (there is no buffer
7950/// allocation retry / re-attempt). If buffer allocation succeeds (or is not
7951/// needed), the logical allocation succeeds.
7952///
7953/// If this prioritization scheme cannot reasonably work for your usage of
7954/// sysmem, please contact sysmem folks to discuss potentially adding a way to
7955/// achieve what you need.
7956///
7957/// Please avoid creating a large number of BufferCollectionTokenGroup(s) per
7958/// logical allocation, especially with large number of children overall, and
7959/// especially in cases where aggregation may reasonably be expected to often
7960/// fail using ordinal 0 children and possibly with later children as well. We
7961/// anticipate mitigating potentially high time complexity of evaluating too
7962/// many child combinations/selections across too many groups by simply failing
7963/// logical allocation beyond a certain (fairly high, but not huge) max number
7964/// of considered group child combinations/selections. More advanced (and more
7965/// complicated) mitigation is not anticipated to be practically necessary or
7966/// worth the added complexity. Please contact sysmem folks if the max limit
7967/// is getting hit or if you anticipate it getting hit, to discuss potential
7968/// options.
7969///
7970/// Prefer to use multiple ImageFormatConstraints in a single
7971/// BufferCollectionConstraints when feasible (when a participant just needs to
7972/// express the ability to work with more than a single PixelFormat, with
7973/// sysmem choosing which PixelFormat to use among those supported by all
7974/// participants).
7975///
7976/// Similar to BufferCollectionToken and BufferCollection, closure of the
7977/// BufferCollectionTokenGroup channel without sending Close() first will cause
7978/// logical buffer collection failure (or sub-tree failure if using
7979/// SetDispensable() or AttachToken() and the BufferCollectionTokenGroup is part
7980/// of a sub-tree under such a node that doesn't propagate failure to its
7981/// parent).
7982#[derive(Debug)]
7983pub enum BufferCollectionTokenGroupRequest {
7984 /// Ensure that previous messages, including Duplicate() messages on a
7985 /// token, collection, or group, have been received server side.
7986 ///
7987 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
7988 /// valid sysmem token risks the Sync() hanging forever. See
7989 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
7990 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
7991 /// Another way is to pass the token to BindSharedCollection(), which also
7992 /// validates the token as part of exchanging it for a BufferCollection
7993 /// channel, and BufferCollection Sync() can then be used.
7994 ///
7995 /// After a Sync(), it's then safe to send the client end of token_request
7996 /// to another participant knowing the server will recognize the token when
7997 /// it's sent into BindSharedCollection() by the other participant.
7998 ///
7999 /// Other options include waiting for each token.Duplicate() to complete
8000 /// individually (using separate call to token.Sync() after each), or
8001 /// calling Sync() on BufferCollection after the token has been turned in
8002 /// via BindSharedCollection().
8003 ///
8004 /// Another way to mitigate is to avoid calling Sync() on the token, and
8005 /// instead later deal with potential failure of BufferCollection.Sync() if
8006 /// the original token was invalid. This option can be preferable from a
8007 /// performance point of view, but requires client code to delay sending
8008 /// tokens duplicated from this token until after client code has converted
8009 /// the duplicating token to a BufferCollection and received successful
8010 /// response from BufferCollection.Sync().
8011 ///
8012 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
8013 /// When BufferCollection.Sync() isn't feasible, the caller must already
8014 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
8015 /// hang forever. See ValidateBufferCollectionToken() to check token
8016 /// validity first if the token isn't already known to be (is/was) valid.
8017 Sync { responder: BufferCollectionTokenGroupSyncResponder },
8018 /// On a BufferCollectionToken channel:
8019 ///
8020 /// Normally a participant will convert a BufferCollectionToken into a
8021 /// BufferCollection view, but a participant is also free to Close() the
8022 /// token (and then close the channel immediately or shortly later in
8023 /// response to server closing its end), which avoids causing logical buffer
8024 /// collection failure. Â Normally an unexpected token channel close will
8025 /// cause logical buffer collection failure (the only exceptions being
8026 /// certain cases involving AttachToken() or SetDispensable()).
8027 ///
8028 /// On a BufferCollection channel:
8029 ///
8030 /// By default the server handles unexpected failure of a BufferCollection
8031 /// by failing the whole logical buffer collection. Partly this is to
8032 /// expedite closing VMO handles to reclaim memory when any participant
8033 /// fails. If a participant would like to cleanly close a BufferCollection
8034 /// view without causing logical buffer collection failure, the participant
8035 /// can send Close() before closing the client end of the BufferCollection
8036 /// channel. If this is the last BufferCollection view, the logical buffer
8037 /// collection will still go away. The Close() can occur before or after
8038 /// SetConstraints(). If before SetConstraints(), the buffer collection
8039 /// won't require constraints from this node in order to allocate. If
8040 /// after SetConstraints(), the constraints are retained and aggregated
8041 /// along with any subsequent logical allocation(s), despite the lack of
8042 /// channel connection.
8043 ///
8044 /// On a BufferCollectionTokenGroup channel:
8045 ///
8046 /// By default, unexpected failure of a BufferCollectionTokenGroup will
8047 /// trigger failure of the logical BufferCollectionTokenGroup and will
8048 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
8049 /// channel without failing the logical group or propagating failure, send
8050 /// Close() before closing the channel client endpoint.
8051 ///
8052 /// If Close() occurs before AllChildrenPresent(), the logical buffer
8053 /// collection will still fail despite the Close() (because sysmem can't be
8054 /// sure whether all relevant children were created, so it's ambiguous
8055 /// whether all relevant constraints will be provided to sysmem). If
8056 /// Close() occurs after AllChildrenPresent(), the children and all their
8057 /// constraints remain intact (just as they would if the
8058 /// BufferCollectionTokenGroup channel had remained open), and the close
8059 /// doesn't trigger or propagate failure.
8060 Close { control_handle: BufferCollectionTokenGroupControlHandle },
8061 /// Set a name for VMOs in this buffer collection. The name may be truncated
8062 /// shorter. The name only affects VMOs allocated after it's set - this call
8063 /// does not rename existing VMOs. If multiple clients set different names
8064 /// then the larger priority value will win.
8065 SetName { priority: u32, name: String, control_handle: BufferCollectionTokenGroupControlHandle },
8066 /// Set information about the current client that can be used by sysmem to
8067 /// help debug leaking memory and hangs waiting for constraints. |name| can
8068 /// be an arbitrary string, but the current process name (see
8069 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
8070 /// arbitrary id, but the current process ID (see
8071 /// fsl::GetCurrentProcessKoid()) is a good default.
8072 ///
8073 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
8074 /// indicate which client is closing their channel first, leading to
8075 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
8076 /// over, but if happening earlier than expected, the
8077 /// client-channel-specific name can help diagnose where the failure is
8078 /// first coming from, from sysmem's point of view).
8079 ///
8080 /// By default (unless overriden by this message or using
8081 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
8082 /// parent Node at the time the child Node is created. While this can be
8083 /// better than nothing, it's often better for each participant to use
8084 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
8085 /// info directly relevant to the current client. Also, SetVerboseLogging()
8086 /// can be used to help disambiguate if a Node is suspected of having info
8087 /// that was copied from its parent.
8088 SetDebugClientInfo {
8089 name: String,
8090 id: u64,
8091 control_handle: BufferCollectionTokenGroupControlHandle,
8092 },
8093 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
8094 /// after creating a collection. Clients can call this method to change
8095 /// when the log is printed. If multiple client set the deadline, it's
8096 /// unspecified which deadline will take effect.
8097 SetDebugTimeoutLogDeadline {
8098 deadline: i64,
8099 control_handle: BufferCollectionTokenGroupControlHandle,
8100 },
8101 /// Verbose logging includes constraints set via SetConstraints() from each
8102 /// client along with info set via SetDebugClientInfo() and the structure of
8103 /// the tree of Node(s).
8104 ///
8105 /// Normally sysmem prints only a single line complaint when aggregation
8106 /// fails, with just the specific detailed reason that aggregation failed,
8107 /// with minimal context. While this is often enough to diagnose a problem
8108 /// if only a small change was made and the system had been working before
8109 /// the small change, it's often not particularly helpful for getting a new
8110 /// buffer collection to work for the first time. Especially with more
8111 /// complex trees of nodes, involving things like AttachToken(),
8112 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
8113 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
8114 /// looks like and why it's failing a logical allocation, or why a tree or
8115 /// sub-tree is failing sooner than expected.
8116 ///
8117 /// The intent of the extra logging is to be acceptable from a performance
8118 /// point of view, if only enabled on a low number of buffer collections.
8119 /// If we're not tracking down a bug, we shouldn't send this message.
8120 ///
8121 /// If too many participants leave verbose logging enabled, we may end up
8122 /// needing to require that system-wide sysmem verbose logging be permitted
8123 /// via some other setting, to avoid sysmem spamming the log too much due to
8124 /// this message.
8125 ///
8126 /// This may be a NOP for some nodes due to intentional policy associated
8127 /// with the node, if we don't trust a node enough to let it turn on verbose
8128 /// logging.
8129 SetVerboseLogging { control_handle: BufferCollectionTokenGroupControlHandle },
8130 /// This gets an event handle that can be used as a parameter to
8131 /// IsAlternateFor() called on any Node. The client will not be granted the
8132 /// right to signal this event, as this handle should only be used as proof
8133 /// that the client obtained this handle from this Node.
8134 ///
8135 /// Because this is a get not a set, no Sync() is needed between the
8136 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
8137 /// potentially being on different channels.
8138 ///
8139 /// See also IsAlternateFor().
8140 GetNodeRef { responder: BufferCollectionTokenGroupGetNodeRefResponder },
8141 /// This checks whether the calling node is in a subtree rooted at a
8142 /// different child token of a common parent BufferCollectionTokenGroup, in
8143 /// relation to the passed-in node_ref.
8144 ///
8145 /// This call is for assisting with admission control de-duplication, and
8146 /// with debugging.
8147 ///
8148 /// The node_ref must be obtained using GetNodeRef() of a
8149 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
8150 ///
8151 /// The node_ref can be a duplicated handle; it's not necessary to call
8152 /// GetNodeRef() for every call to IsAlternateFor().
8153 ///
8154 /// If a calling token may not actually be a valid token at all due to
8155 /// a potentially hostile/untrusted provider of the token, call
8156 /// ValidateBufferCollectionToken() first instead of potentially getting
8157 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
8158 /// token not being a real token (not really talking to sysmem). Another
8159 /// option is to call BindSharedCollection with this token first which also
8160 /// validates the token along with converting it to a BufferCollection, then
8161 /// call BufferCollection IsAlternateFor().
8162 ///
8163 /// error values:
8164 ///
8165 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
8166 /// buffer collection as the calling Node. Before logical allocation and
8167 /// within the same logical allocation sub-tree, this essentially means that
8168 /// the node_ref was never part of this logical buffer collection, since
8169 /// before logical allocation all node_refs that come into existence remain
8170 /// in existence at least until logical allocation (including Node(s) that
8171 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
8172 /// to be returned, this Node's channel needs to still be connected server
8173 /// side, which won't be the case if the whole logical allocation has
8174 /// failed. After logical allocation or in a different logical allocation
8175 /// sub-tree there are additional potential reasons for this error. For
8176 /// example a different logical allocation (separated from this Node(s)
8177 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
8178 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
8179 /// exist and may select a different child sub-tree than the sub-tree the
8180 /// node_ref is in causing deletion of the node_ref Node. The only time
8181 /// sysmem keeps a Node around after that Node has no corresponding channel
8182 /// is when Close() is used and the Node's sub-tree has not yet failed.
8183 /// Another reason for this error is if the node_ref is an eventpair handle
8184 /// with sufficient rights, but isn't actually a real node_ref obtained from
8185 /// GetNodeRef().
8186 ///
8187 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
8188 /// eventpair handle, or doesn't have the needed rights expected on a real
8189 /// node_ref.
8190 ///
8191 /// No other failing status codes are returned by this call. However,
8192 /// sysmem may add additional codes in future, so the client should have
8193 /// sensible default handling for any failing status code.
8194 ///
8195 /// On success, is_alternate has the following meaning:
8196 /// * true - The first parent node in common between the calling node and
8197 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
8198 /// the calling Node and the node_ref Node will _not_ have both their
8199 /// constraints apply - rather sysmem will choose one or the other of
8200 /// the constraints - never both. This is because only one child of
8201 /// a BufferCollectionTokenGroup is selected during logical allocation,
8202 /// with only that one child's sub-tree contributing to constraints
8203 /// aggregation.
8204 /// * false - The first parent node in common between the calling Node and
8205 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
8206 /// this means the first parent node in common is a
8207 /// BufferCollectionToken or BufferCollection (regardless of not
8208 /// Close()ed or Close()ed). This means that the calling Node and the
8209 /// node_ref Node _may_ have both their constraints apply during
8210 /// constraints aggregation of the logical allocation, if both Node(s)
8211 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
8212 /// In this case, there is no BufferCollectionTokenGroup that will
8213 /// directly prevent the two Node(s) from both being selected and their
8214 /// constraints both aggregated, but even when false, one or both
8215 /// Node(s) may still be eliminated from consideration if one or both
8216 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
8217 /// which selects a child sub-tree other than the sub-tree containing
8218 /// the calling Node or node_ref Node.
8219 IsAlternateFor {
8220 node_ref: fidl::Event,
8221 responder: BufferCollectionTokenGroupIsAlternateForResponder,
8222 },
8223 /// Create a child token. Before passing the client end of this token to
8224 /// BindSharedCollection(), completion of Sync() after CreateChild() is
8225 /// required. Or the client can use CreateChildrenSync() which essentially
8226 /// includes the Sync().
8227 ///
8228 /// token_request - the server end of the new token channel.
8229 ///
8230 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
8231 /// allows the holder to get the same rights to buffers as the parent token
8232 /// (of the group) had.
8233 CreateChild {
8234 payload: BufferCollectionTokenGroupCreateChildRequest,
8235 control_handle: BufferCollectionTokenGroupControlHandle,
8236 },
8237 /// Create 1 or more child tokens at once, synchronously. In contrast to
8238 /// CreateChild(), no Sync() completion is required before passing the
8239 /// client end of a returned token to BindSharedCollection().
8240 ///
8241 /// The size of the rights_attentuation_mask determines the number of
8242 /// created child tokens.
8243 ///
8244 /// The lower-index child tokens are higher priority (attempted sooner) than
8245 /// higher-index child tokens.
8246 ///
8247 /// As per all child tokens, successful aggregation will choose exactly one
8248 /// child among all created children (across all children created across
8249 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
8250 ///
8251 /// The maximum permissible total number of children per group, and total
8252 /// number of nodes in an overall tree (from the root) are capped to limits
8253 /// which are not configurable via these protocols.
8254 CreateChildrenSync {
8255 rights_attenuation_masks: Vec<fidl::Rights>,
8256 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder,
8257 },
8258 /// AllChildrenPresent()
8259 ///
8260 /// After creating all children, the client must call AllChildrenPresent()
8261 /// to inform sysmem that no more children will be created, so that sysmem
8262 /// can know when it's ok to start aggregating constraints.
8263 ///
8264 /// If Close() is to be sent, it should be sent _after_
8265 /// AllChildrenPresent(), else failure of the group and propagation of the
8266 /// failure to the group's parent will still be triggered.
8267 AllChildrenPresent { control_handle: BufferCollectionTokenGroupControlHandle },
8268}
8269
8270impl BufferCollectionTokenGroupRequest {
8271 #[allow(irrefutable_let_patterns)]
8272 pub fn into_sync(self) -> Option<(BufferCollectionTokenGroupSyncResponder)> {
8273 if let BufferCollectionTokenGroupRequest::Sync { responder } = self {
8274 Some((responder))
8275 } else {
8276 None
8277 }
8278 }
8279
8280 #[allow(irrefutable_let_patterns)]
8281 pub fn into_close(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8282 if let BufferCollectionTokenGroupRequest::Close { control_handle } = self {
8283 Some((control_handle))
8284 } else {
8285 None
8286 }
8287 }
8288
8289 #[allow(irrefutable_let_patterns)]
8290 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionTokenGroupControlHandle)> {
8291 if let BufferCollectionTokenGroupRequest::SetName { priority, name, control_handle } = self
8292 {
8293 Some((priority, name, control_handle))
8294 } else {
8295 None
8296 }
8297 }
8298
8299 #[allow(irrefutable_let_patterns)]
8300 pub fn into_set_debug_client_info(
8301 self,
8302 ) -> Option<(String, u64, BufferCollectionTokenGroupControlHandle)> {
8303 if let BufferCollectionTokenGroupRequest::SetDebugClientInfo { name, id, control_handle } =
8304 self
8305 {
8306 Some((name, id, control_handle))
8307 } else {
8308 None
8309 }
8310 }
8311
8312 #[allow(irrefutable_let_patterns)]
8313 pub fn into_set_debug_timeout_log_deadline(
8314 self,
8315 ) -> Option<(i64, BufferCollectionTokenGroupControlHandle)> {
8316 if let BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {
8317 deadline,
8318 control_handle,
8319 } = self
8320 {
8321 Some((deadline, control_handle))
8322 } else {
8323 None
8324 }
8325 }
8326
8327 #[allow(irrefutable_let_patterns)]
8328 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8329 if let BufferCollectionTokenGroupRequest::SetVerboseLogging { control_handle } = self {
8330 Some((control_handle))
8331 } else {
8332 None
8333 }
8334 }
8335
8336 #[allow(irrefutable_let_patterns)]
8337 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGroupGetNodeRefResponder)> {
8338 if let BufferCollectionTokenGroupRequest::GetNodeRef { responder } = self {
8339 Some((responder))
8340 } else {
8341 None
8342 }
8343 }
8344
8345 #[allow(irrefutable_let_patterns)]
8346 pub fn into_is_alternate_for(
8347 self,
8348 ) -> Option<(fidl::Event, BufferCollectionTokenGroupIsAlternateForResponder)> {
8349 if let BufferCollectionTokenGroupRequest::IsAlternateFor { node_ref, responder } = self {
8350 Some((node_ref, responder))
8351 } else {
8352 None
8353 }
8354 }
8355
8356 #[allow(irrefutable_let_patterns)]
8357 pub fn into_create_child(
8358 self,
8359 ) -> Option<(
8360 BufferCollectionTokenGroupCreateChildRequest,
8361 BufferCollectionTokenGroupControlHandle,
8362 )> {
8363 if let BufferCollectionTokenGroupRequest::CreateChild { payload, control_handle } = self {
8364 Some((payload, control_handle))
8365 } else {
8366 None
8367 }
8368 }
8369
8370 #[allow(irrefutable_let_patterns)]
8371 pub fn into_create_children_sync(
8372 self,
8373 ) -> Option<(Vec<fidl::Rights>, BufferCollectionTokenGroupCreateChildrenSyncResponder)> {
8374 if let BufferCollectionTokenGroupRequest::CreateChildrenSync {
8375 rights_attenuation_masks,
8376 responder,
8377 } = self
8378 {
8379 Some((rights_attenuation_masks, responder))
8380 } else {
8381 None
8382 }
8383 }
8384
8385 #[allow(irrefutable_let_patterns)]
8386 pub fn into_all_children_present(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8387 if let BufferCollectionTokenGroupRequest::AllChildrenPresent { control_handle } = self {
8388 Some((control_handle))
8389 } else {
8390 None
8391 }
8392 }
8393
8394 /// Name of the method defined in FIDL
8395 pub fn method_name(&self) -> &'static str {
8396 match *self {
8397 BufferCollectionTokenGroupRequest::Sync { .. } => "sync",
8398 BufferCollectionTokenGroupRequest::Close { .. } => "close",
8399 BufferCollectionTokenGroupRequest::SetName { .. } => "set_name",
8400 BufferCollectionTokenGroupRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
8401 BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline { .. } => {
8402 "set_debug_timeout_log_deadline"
8403 }
8404 BufferCollectionTokenGroupRequest::SetVerboseLogging { .. } => "set_verbose_logging",
8405 BufferCollectionTokenGroupRequest::GetNodeRef { .. } => "get_node_ref",
8406 BufferCollectionTokenGroupRequest::IsAlternateFor { .. } => "is_alternate_for",
8407 BufferCollectionTokenGroupRequest::CreateChild { .. } => "create_child",
8408 BufferCollectionTokenGroupRequest::CreateChildrenSync { .. } => "create_children_sync",
8409 BufferCollectionTokenGroupRequest::AllChildrenPresent { .. } => "all_children_present",
8410 }
8411 }
8412}
8413
8414#[derive(Debug, Clone)]
8415pub struct BufferCollectionTokenGroupControlHandle {
8416 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
8417}
8418
8419impl fidl::endpoints::ControlHandle for BufferCollectionTokenGroupControlHandle {
8420 fn shutdown(&self) {
8421 self.inner.shutdown()
8422 }
8423 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
8424 self.inner.shutdown_with_epitaph(status)
8425 }
8426
8427 fn is_closed(&self) -> bool {
8428 self.inner.channel().is_closed()
8429 }
8430 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
8431 self.inner.channel().on_closed()
8432 }
8433
8434 #[cfg(target_os = "fuchsia")]
8435 fn signal_peer(
8436 &self,
8437 clear_mask: zx::Signals,
8438 set_mask: zx::Signals,
8439 ) -> Result<(), zx_status::Status> {
8440 use fidl::Peered;
8441 self.inner.channel().signal_peer(clear_mask, set_mask)
8442 }
8443}
8444
8445impl BufferCollectionTokenGroupControlHandle {}
8446
8447#[must_use = "FIDL methods require a response to be sent"]
8448#[derive(Debug)]
8449pub struct BufferCollectionTokenGroupSyncResponder {
8450 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8451 tx_id: u32,
8452}
8453
8454/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8455/// if the responder is dropped without sending a response, so that the client
8456/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8457impl std::ops::Drop for BufferCollectionTokenGroupSyncResponder {
8458 fn drop(&mut self) {
8459 self.control_handle.shutdown();
8460 // Safety: drops once, never accessed again
8461 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8462 }
8463}
8464
8465impl fidl::endpoints::Responder for BufferCollectionTokenGroupSyncResponder {
8466 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8467
8468 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8469 &self.control_handle
8470 }
8471
8472 fn drop_without_shutdown(mut self) {
8473 // Safety: drops once, never accessed again due to mem::forget
8474 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8475 // Prevent Drop from running (which would shut down the channel)
8476 std::mem::forget(self);
8477 }
8478}
8479
8480impl BufferCollectionTokenGroupSyncResponder {
8481 /// Sends a response to the FIDL transaction.
8482 ///
8483 /// Sets the channel to shutdown if an error occurs.
8484 pub fn send(self) -> Result<(), fidl::Error> {
8485 let _result = self.send_raw();
8486 if _result.is_err() {
8487 self.control_handle.shutdown();
8488 }
8489 self.drop_without_shutdown();
8490 _result
8491 }
8492
8493 /// Similar to "send" but does not shutdown the channel if an error occurs.
8494 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
8495 let _result = self.send_raw();
8496 self.drop_without_shutdown();
8497 _result
8498 }
8499
8500 fn send_raw(&self) -> Result<(), fidl::Error> {
8501 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
8502 (),
8503 self.tx_id,
8504 0x4577e238ae26291,
8505 fidl::encoding::DynamicFlags::empty(),
8506 )
8507 }
8508}
8509
8510#[must_use = "FIDL methods require a response to be sent"]
8511#[derive(Debug)]
8512pub struct BufferCollectionTokenGroupGetNodeRefResponder {
8513 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8514 tx_id: u32,
8515}
8516
8517/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8518/// if the responder is dropped without sending a response, so that the client
8519/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8520impl std::ops::Drop for BufferCollectionTokenGroupGetNodeRefResponder {
8521 fn drop(&mut self) {
8522 self.control_handle.shutdown();
8523 // Safety: drops once, never accessed again
8524 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8525 }
8526}
8527
8528impl fidl::endpoints::Responder for BufferCollectionTokenGroupGetNodeRefResponder {
8529 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8530
8531 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8532 &self.control_handle
8533 }
8534
8535 fn drop_without_shutdown(mut self) {
8536 // Safety: drops once, never accessed again due to mem::forget
8537 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8538 // Prevent Drop from running (which would shut down the channel)
8539 std::mem::forget(self);
8540 }
8541}
8542
8543impl BufferCollectionTokenGroupGetNodeRefResponder {
8544 /// Sends a response to the FIDL transaction.
8545 ///
8546 /// Sets the channel to shutdown if an error occurs.
8547 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8548 let _result = self.send_raw(node_ref);
8549 if _result.is_err() {
8550 self.control_handle.shutdown();
8551 }
8552 self.drop_without_shutdown();
8553 _result
8554 }
8555
8556 /// Similar to "send" but does not shutdown the channel if an error occurs.
8557 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8558 let _result = self.send_raw(node_ref);
8559 self.drop_without_shutdown();
8560 _result
8561 }
8562
8563 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8564 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
8565 (node_ref,),
8566 self.tx_id,
8567 0x467b7c75c35c3b84,
8568 fidl::encoding::DynamicFlags::empty(),
8569 )
8570 }
8571}
8572
8573#[must_use = "FIDL methods require a response to be sent"]
8574#[derive(Debug)]
8575pub struct BufferCollectionTokenGroupIsAlternateForResponder {
8576 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8577 tx_id: u32,
8578}
8579
8580/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8581/// if the responder is dropped without sending a response, so that the client
8582/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8583impl std::ops::Drop for BufferCollectionTokenGroupIsAlternateForResponder {
8584 fn drop(&mut self) {
8585 self.control_handle.shutdown();
8586 // Safety: drops once, never accessed again
8587 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8588 }
8589}
8590
8591impl fidl::endpoints::Responder for BufferCollectionTokenGroupIsAlternateForResponder {
8592 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8593
8594 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8595 &self.control_handle
8596 }
8597
8598 fn drop_without_shutdown(mut self) {
8599 // Safety: drops once, never accessed again due to mem::forget
8600 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8601 // Prevent Drop from running (which would shut down the channel)
8602 std::mem::forget(self);
8603 }
8604}
8605
8606impl BufferCollectionTokenGroupIsAlternateForResponder {
8607 /// Sends a response to the FIDL transaction.
8608 ///
8609 /// Sets the channel to shutdown if an error occurs.
8610 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8611 let _result = self.send_raw(result);
8612 if _result.is_err() {
8613 self.control_handle.shutdown();
8614 }
8615 self.drop_without_shutdown();
8616 _result
8617 }
8618
8619 /// Similar to "send" but does not shutdown the channel if an error occurs.
8620 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8621 let _result = self.send_raw(result);
8622 self.drop_without_shutdown();
8623 _result
8624 }
8625
8626 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8627 self.control_handle
8628 .inner
8629 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
8630 result.map(|is_alternate| (is_alternate,)),
8631 self.tx_id,
8632 0x33a2a7aff2776c07,
8633 fidl::encoding::DynamicFlags::empty(),
8634 )
8635 }
8636}
8637
8638#[must_use = "FIDL methods require a response to be sent"]
8639#[derive(Debug)]
8640pub struct BufferCollectionTokenGroupCreateChildrenSyncResponder {
8641 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8642 tx_id: u32,
8643}
8644
8645/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8646/// if the responder is dropped without sending a response, so that the client
8647/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8648impl std::ops::Drop for BufferCollectionTokenGroupCreateChildrenSyncResponder {
8649 fn drop(&mut self) {
8650 self.control_handle.shutdown();
8651 // Safety: drops once, never accessed again
8652 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8653 }
8654}
8655
8656impl fidl::endpoints::Responder for BufferCollectionTokenGroupCreateChildrenSyncResponder {
8657 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8658
8659 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8660 &self.control_handle
8661 }
8662
8663 fn drop_without_shutdown(mut self) {
8664 // Safety: drops once, never accessed again due to mem::forget
8665 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8666 // Prevent Drop from running (which would shut down the channel)
8667 std::mem::forget(self);
8668 }
8669}
8670
8671impl BufferCollectionTokenGroupCreateChildrenSyncResponder {
8672 /// Sends a response to the FIDL transaction.
8673 ///
8674 /// Sets the channel to shutdown if an error occurs.
8675 pub fn send(
8676 self,
8677 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8678 ) -> Result<(), fidl::Error> {
8679 let _result = self.send_raw(tokens);
8680 if _result.is_err() {
8681 self.control_handle.shutdown();
8682 }
8683 self.drop_without_shutdown();
8684 _result
8685 }
8686
8687 /// Similar to "send" but does not shutdown the channel if an error occurs.
8688 pub fn send_no_shutdown_on_err(
8689 self,
8690 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8691 ) -> Result<(), fidl::Error> {
8692 let _result = self.send_raw(tokens);
8693 self.drop_without_shutdown();
8694 _result
8695 }
8696
8697 fn send_raw(
8698 &self,
8699 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8700 ) -> Result<(), fidl::Error> {
8701 self.control_handle.inner.send::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(
8702 (tokens.as_mut(),),
8703 self.tx_id,
8704 0x569dc3ca2a98f535,
8705 fidl::encoding::DynamicFlags::empty(),
8706 )
8707 }
8708}
8709
8710#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
8711pub struct NodeMarker;
8712
8713impl fidl::endpoints::ProtocolMarker for NodeMarker {
8714 type Proxy = NodeProxy;
8715 type RequestStream = NodeRequestStream;
8716 #[cfg(target_os = "fuchsia")]
8717 type SynchronousProxy = NodeSynchronousProxy;
8718
8719 const DEBUG_NAME: &'static str = "(anonymous) Node";
8720}
8721pub type NodeIsAlternateForResult = Result<bool, i32>;
8722
8723pub trait NodeProxyInterface: Send + Sync {
8724 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
8725 fn r#sync(&self) -> Self::SyncResponseFut;
8726 fn r#close(&self) -> Result<(), fidl::Error>;
8727 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
8728 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
8729 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
8730 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
8731 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
8732 + Send;
8733 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
8734 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
8735 + Send;
8736 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
8737}
8738#[derive(Debug)]
8739#[cfg(target_os = "fuchsia")]
8740pub struct NodeSynchronousProxy {
8741 client: fidl::client::sync::Client,
8742}
8743
8744#[cfg(target_os = "fuchsia")]
8745impl fidl::endpoints::SynchronousProxy for NodeSynchronousProxy {
8746 type Proxy = NodeProxy;
8747 type Protocol = NodeMarker;
8748
8749 fn from_channel(inner: fidl::Channel) -> Self {
8750 Self::new(inner)
8751 }
8752
8753 fn into_channel(self) -> fidl::Channel {
8754 self.client.into_channel()
8755 }
8756
8757 fn as_channel(&self) -> &fidl::Channel {
8758 self.client.as_channel()
8759 }
8760}
8761
8762#[cfg(target_os = "fuchsia")]
8763impl NodeSynchronousProxy {
8764 pub fn new(channel: fidl::Channel) -> Self {
8765 let protocol_name = <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
8766 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
8767 }
8768
8769 pub fn into_channel(self) -> fidl::Channel {
8770 self.client.into_channel()
8771 }
8772
8773 /// Waits until an event arrives and returns it. It is safe for other
8774 /// threads to make concurrent requests while waiting for an event.
8775 pub fn wait_for_event(&self, deadline: zx::MonotonicInstant) -> Result<NodeEvent, fidl::Error> {
8776 NodeEvent::decode(self.client.wait_for_event(deadline)?)
8777 }
8778
8779 /// Ensure that previous messages, including Duplicate() messages on a
8780 /// token, collection, or group, have been received server side.
8781 ///
8782 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
8783 /// valid sysmem token risks the Sync() hanging forever. See
8784 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
8785 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
8786 /// Another way is to pass the token to BindSharedCollection(), which also
8787 /// validates the token as part of exchanging it for a BufferCollection
8788 /// channel, and BufferCollection Sync() can then be used.
8789 ///
8790 /// After a Sync(), it's then safe to send the client end of token_request
8791 /// to another participant knowing the server will recognize the token when
8792 /// it's sent into BindSharedCollection() by the other participant.
8793 ///
8794 /// Other options include waiting for each token.Duplicate() to complete
8795 /// individually (using separate call to token.Sync() after each), or
8796 /// calling Sync() on BufferCollection after the token has been turned in
8797 /// via BindSharedCollection().
8798 ///
8799 /// Another way to mitigate is to avoid calling Sync() on the token, and
8800 /// instead later deal with potential failure of BufferCollection.Sync() if
8801 /// the original token was invalid. This option can be preferable from a
8802 /// performance point of view, but requires client code to delay sending
8803 /// tokens duplicated from this token until after client code has converted
8804 /// the duplicating token to a BufferCollection and received successful
8805 /// response from BufferCollection.Sync().
8806 ///
8807 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
8808 /// When BufferCollection.Sync() isn't feasible, the caller must already
8809 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
8810 /// hang forever. See ValidateBufferCollectionToken() to check token
8811 /// validity first if the token isn't already known to be (is/was) valid.
8812 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
8813 let _response =
8814 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
8815 (),
8816 0x4577e238ae26291,
8817 fidl::encoding::DynamicFlags::empty(),
8818 ___deadline,
8819 )?;
8820 Ok(_response)
8821 }
8822
8823 /// On a BufferCollectionToken channel:
8824 ///
8825 /// Normally a participant will convert a BufferCollectionToken into a
8826 /// BufferCollection view, but a participant is also free to Close() the
8827 /// token (and then close the channel immediately or shortly later in
8828 /// response to server closing its end), which avoids causing logical buffer
8829 /// collection failure. Â Normally an unexpected token channel close will
8830 /// cause logical buffer collection failure (the only exceptions being
8831 /// certain cases involving AttachToken() or SetDispensable()).
8832 ///
8833 /// On a BufferCollection channel:
8834 ///
8835 /// By default the server handles unexpected failure of a BufferCollection
8836 /// by failing the whole logical buffer collection. Partly this is to
8837 /// expedite closing VMO handles to reclaim memory when any participant
8838 /// fails. If a participant would like to cleanly close a BufferCollection
8839 /// view without causing logical buffer collection failure, the participant
8840 /// can send Close() before closing the client end of the BufferCollection
8841 /// channel. If this is the last BufferCollection view, the logical buffer
8842 /// collection will still go away. The Close() can occur before or after
8843 /// SetConstraints(). If before SetConstraints(), the buffer collection
8844 /// won't require constraints from this node in order to allocate. If
8845 /// after SetConstraints(), the constraints are retained and aggregated
8846 /// along with any subsequent logical allocation(s), despite the lack of
8847 /// channel connection.
8848 ///
8849 /// On a BufferCollectionTokenGroup channel:
8850 ///
8851 /// By default, unexpected failure of a BufferCollectionTokenGroup will
8852 /// trigger failure of the logical BufferCollectionTokenGroup and will
8853 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
8854 /// channel without failing the logical group or propagating failure, send
8855 /// Close() before closing the channel client endpoint.
8856 ///
8857 /// If Close() occurs before AllChildrenPresent(), the logical buffer
8858 /// collection will still fail despite the Close() (because sysmem can't be
8859 /// sure whether all relevant children were created, so it's ambiguous
8860 /// whether all relevant constraints will be provided to sysmem). If
8861 /// Close() occurs after AllChildrenPresent(), the children and all their
8862 /// constraints remain intact (just as they would if the
8863 /// BufferCollectionTokenGroup channel had remained open), and the close
8864 /// doesn't trigger or propagate failure.
8865 pub fn r#close(&self) -> Result<(), fidl::Error> {
8866 self.client.send::<fidl::encoding::EmptyPayload>(
8867 (),
8868 0x5b1d7a4f5681fca7,
8869 fidl::encoding::DynamicFlags::empty(),
8870 )
8871 }
8872
8873 /// Set a name for VMOs in this buffer collection. The name may be truncated
8874 /// shorter. The name only affects VMOs allocated after it's set - this call
8875 /// does not rename existing VMOs. If multiple clients set different names
8876 /// then the larger priority value will win.
8877 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
8878 self.client.send::<NodeSetNameRequest>(
8879 (priority, name),
8880 0x77a41bb6217e2443,
8881 fidl::encoding::DynamicFlags::empty(),
8882 )
8883 }
8884
8885 /// Set information about the current client that can be used by sysmem to
8886 /// help debug leaking memory and hangs waiting for constraints. |name| can
8887 /// be an arbitrary string, but the current process name (see
8888 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
8889 /// arbitrary id, but the current process ID (see
8890 /// fsl::GetCurrentProcessKoid()) is a good default.
8891 ///
8892 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
8893 /// indicate which client is closing their channel first, leading to
8894 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
8895 /// over, but if happening earlier than expected, the
8896 /// client-channel-specific name can help diagnose where the failure is
8897 /// first coming from, from sysmem's point of view).
8898 ///
8899 /// By default (unless overriden by this message or using
8900 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
8901 /// parent Node at the time the child Node is created. While this can be
8902 /// better than nothing, it's often better for each participant to use
8903 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
8904 /// info directly relevant to the current client. Also, SetVerboseLogging()
8905 /// can be used to help disambiguate if a Node is suspected of having info
8906 /// that was copied from its parent.
8907 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
8908 self.client.send::<NodeSetDebugClientInfoRequest>(
8909 (name, id),
8910 0x7275759070eb5ee2,
8911 fidl::encoding::DynamicFlags::empty(),
8912 )
8913 }
8914
8915 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
8916 /// after creating a collection. Clients can call this method to change
8917 /// when the log is printed. If multiple client set the deadline, it's
8918 /// unspecified which deadline will take effect.
8919 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
8920 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
8921 (deadline,),
8922 0x46d38f4772638867,
8923 fidl::encoding::DynamicFlags::empty(),
8924 )
8925 }
8926
8927 /// Verbose logging includes constraints set via SetConstraints() from each
8928 /// client along with info set via SetDebugClientInfo() and the structure of
8929 /// the tree of Node(s).
8930 ///
8931 /// Normally sysmem prints only a single line complaint when aggregation
8932 /// fails, with just the specific detailed reason that aggregation failed,
8933 /// with minimal context. While this is often enough to diagnose a problem
8934 /// if only a small change was made and the system had been working before
8935 /// the small change, it's often not particularly helpful for getting a new
8936 /// buffer collection to work for the first time. Especially with more
8937 /// complex trees of nodes, involving things like AttachToken(),
8938 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
8939 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
8940 /// looks like and why it's failing a logical allocation, or why a tree or
8941 /// sub-tree is failing sooner than expected.
8942 ///
8943 /// The intent of the extra logging is to be acceptable from a performance
8944 /// point of view, if only enabled on a low number of buffer collections.
8945 /// If we're not tracking down a bug, we shouldn't send this message.
8946 ///
8947 /// If too many participants leave verbose logging enabled, we may end up
8948 /// needing to require that system-wide sysmem verbose logging be permitted
8949 /// via some other setting, to avoid sysmem spamming the log too much due to
8950 /// this message.
8951 ///
8952 /// This may be a NOP for some nodes due to intentional policy associated
8953 /// with the node, if we don't trust a node enough to let it turn on verbose
8954 /// logging.
8955 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
8956 self.client.send::<fidl::encoding::EmptyPayload>(
8957 (),
8958 0x6bfbe2cf1701d288,
8959 fidl::encoding::DynamicFlags::empty(),
8960 )
8961 }
8962
8963 /// This gets an event handle that can be used as a parameter to
8964 /// IsAlternateFor() called on any Node. The client will not be granted the
8965 /// right to signal this event, as this handle should only be used as proof
8966 /// that the client obtained this handle from this Node.
8967 ///
8968 /// Because this is a get not a set, no Sync() is needed between the
8969 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
8970 /// potentially being on different channels.
8971 ///
8972 /// See also IsAlternateFor().
8973 pub fn r#get_node_ref(
8974 &self,
8975 ___deadline: zx::MonotonicInstant,
8976 ) -> Result<fidl::Event, fidl::Error> {
8977 let _response =
8978 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
8979 (),
8980 0x467b7c75c35c3b84,
8981 fidl::encoding::DynamicFlags::empty(),
8982 ___deadline,
8983 )?;
8984 Ok(_response.node_ref)
8985 }
8986
8987 /// This checks whether the calling node is in a subtree rooted at a
8988 /// different child token of a common parent BufferCollectionTokenGroup, in
8989 /// relation to the passed-in node_ref.
8990 ///
8991 /// This call is for assisting with admission control de-duplication, and
8992 /// with debugging.
8993 ///
8994 /// The node_ref must be obtained using GetNodeRef() of a
8995 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
8996 ///
8997 /// The node_ref can be a duplicated handle; it's not necessary to call
8998 /// GetNodeRef() for every call to IsAlternateFor().
8999 ///
9000 /// If a calling token may not actually be a valid token at all due to
9001 /// a potentially hostile/untrusted provider of the token, call
9002 /// ValidateBufferCollectionToken() first instead of potentially getting
9003 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
9004 /// token not being a real token (not really talking to sysmem). Another
9005 /// option is to call BindSharedCollection with this token first which also
9006 /// validates the token along with converting it to a BufferCollection, then
9007 /// call BufferCollection IsAlternateFor().
9008 ///
9009 /// error values:
9010 ///
9011 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
9012 /// buffer collection as the calling Node. Before logical allocation and
9013 /// within the same logical allocation sub-tree, this essentially means that
9014 /// the node_ref was never part of this logical buffer collection, since
9015 /// before logical allocation all node_refs that come into existence remain
9016 /// in existence at least until logical allocation (including Node(s) that
9017 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
9018 /// to be returned, this Node's channel needs to still be connected server
9019 /// side, which won't be the case if the whole logical allocation has
9020 /// failed. After logical allocation or in a different logical allocation
9021 /// sub-tree there are additional potential reasons for this error. For
9022 /// example a different logical allocation (separated from this Node(s)
9023 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
9024 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
9025 /// exist and may select a different child sub-tree than the sub-tree the
9026 /// node_ref is in causing deletion of the node_ref Node. The only time
9027 /// sysmem keeps a Node around after that Node has no corresponding channel
9028 /// is when Close() is used and the Node's sub-tree has not yet failed.
9029 /// Another reason for this error is if the node_ref is an eventpair handle
9030 /// with sufficient rights, but isn't actually a real node_ref obtained from
9031 /// GetNodeRef().
9032 ///
9033 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
9034 /// eventpair handle, or doesn't have the needed rights expected on a real
9035 /// node_ref.
9036 ///
9037 /// No other failing status codes are returned by this call. However,
9038 /// sysmem may add additional codes in future, so the client should have
9039 /// sensible default handling for any failing status code.
9040 ///
9041 /// On success, is_alternate has the following meaning:
9042 /// * true - The first parent node in common between the calling node and
9043 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
9044 /// the calling Node and the node_ref Node will _not_ have both their
9045 /// constraints apply - rather sysmem will choose one or the other of
9046 /// the constraints - never both. This is because only one child of
9047 /// a BufferCollectionTokenGroup is selected during logical allocation,
9048 /// with only that one child's sub-tree contributing to constraints
9049 /// aggregation.
9050 /// * false - The first parent node in common between the calling Node and
9051 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
9052 /// this means the first parent node in common is a
9053 /// BufferCollectionToken or BufferCollection (regardless of not
9054 /// Close()ed or Close()ed). This means that the calling Node and the
9055 /// node_ref Node _may_ have both their constraints apply during
9056 /// constraints aggregation of the logical allocation, if both Node(s)
9057 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
9058 /// In this case, there is no BufferCollectionTokenGroup that will
9059 /// directly prevent the two Node(s) from both being selected and their
9060 /// constraints both aggregated, but even when false, one or both
9061 /// Node(s) may still be eliminated from consideration if one or both
9062 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
9063 /// which selects a child sub-tree other than the sub-tree containing
9064 /// the calling Node or node_ref Node.
9065 pub fn r#is_alternate_for(
9066 &self,
9067 mut node_ref: fidl::Event,
9068 ___deadline: zx::MonotonicInstant,
9069 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
9070 let _response = self.client.send_query::<
9071 NodeIsAlternateForRequest,
9072 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
9073 >(
9074 (node_ref,),
9075 0x33a2a7aff2776c07,
9076 fidl::encoding::DynamicFlags::empty(),
9077 ___deadline,
9078 )?;
9079 Ok(_response.map(|x| x.is_alternate))
9080 }
9081}
9082
9083#[derive(Debug, Clone)]
9084pub struct NodeProxy {
9085 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
9086}
9087
9088impl fidl::endpoints::Proxy for NodeProxy {
9089 type Protocol = NodeMarker;
9090
9091 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
9092 Self::new(inner)
9093 }
9094
9095 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
9096 self.client.into_channel().map_err(|client| Self { client })
9097 }
9098
9099 fn as_channel(&self) -> &::fidl::AsyncChannel {
9100 self.client.as_channel()
9101 }
9102}
9103
9104impl NodeProxy {
9105 /// Create a new Proxy for fuchsia.sysmem/Node.
9106 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
9107 let protocol_name = <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
9108 Self { client: fidl::client::Client::new(channel, protocol_name) }
9109 }
9110
9111 /// Get a Stream of events from the remote end of the protocol.
9112 ///
9113 /// # Panics
9114 ///
9115 /// Panics if the event stream was already taken.
9116 pub fn take_event_stream(&self) -> NodeEventStream {
9117 NodeEventStream { event_receiver: self.client.take_event_receiver() }
9118 }
9119
9120 /// Ensure that previous messages, including Duplicate() messages on a
9121 /// token, collection, or group, have been received server side.
9122 ///
9123 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
9124 /// valid sysmem token risks the Sync() hanging forever. See
9125 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
9126 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
9127 /// Another way is to pass the token to BindSharedCollection(), which also
9128 /// validates the token as part of exchanging it for a BufferCollection
9129 /// channel, and BufferCollection Sync() can then be used.
9130 ///
9131 /// After a Sync(), it's then safe to send the client end of token_request
9132 /// to another participant knowing the server will recognize the token when
9133 /// it's sent into BindSharedCollection() by the other participant.
9134 ///
9135 /// Other options include waiting for each token.Duplicate() to complete
9136 /// individually (using separate call to token.Sync() after each), or
9137 /// calling Sync() on BufferCollection after the token has been turned in
9138 /// via BindSharedCollection().
9139 ///
9140 /// Another way to mitigate is to avoid calling Sync() on the token, and
9141 /// instead later deal with potential failure of BufferCollection.Sync() if
9142 /// the original token was invalid. This option can be preferable from a
9143 /// performance point of view, but requires client code to delay sending
9144 /// tokens duplicated from this token until after client code has converted
9145 /// the duplicating token to a BufferCollection and received successful
9146 /// response from BufferCollection.Sync().
9147 ///
9148 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
9149 /// When BufferCollection.Sync() isn't feasible, the caller must already
9150 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
9151 /// hang forever. See ValidateBufferCollectionToken() to check token
9152 /// validity first if the token isn't already known to be (is/was) valid.
9153 pub fn r#sync(
9154 &self,
9155 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
9156 NodeProxyInterface::r#sync(self)
9157 }
9158
9159 /// On a BufferCollectionToken channel:
9160 ///
9161 /// Normally a participant will convert a BufferCollectionToken into a
9162 /// BufferCollection view, but a participant is also free to Close() the
9163 /// token (and then close the channel immediately or shortly later in
9164 /// response to server closing its end), which avoids causing logical buffer
9165 /// collection failure. Â Normally an unexpected token channel close will
9166 /// cause logical buffer collection failure (the only exceptions being
9167 /// certain cases involving AttachToken() or SetDispensable()).
9168 ///
9169 /// On a BufferCollection channel:
9170 ///
9171 /// By default the server handles unexpected failure of a BufferCollection
9172 /// by failing the whole logical buffer collection. Partly this is to
9173 /// expedite closing VMO handles to reclaim memory when any participant
9174 /// fails. If a participant would like to cleanly close a BufferCollection
9175 /// view without causing logical buffer collection failure, the participant
9176 /// can send Close() before closing the client end of the BufferCollection
9177 /// channel. If this is the last BufferCollection view, the logical buffer
9178 /// collection will still go away. The Close() can occur before or after
9179 /// SetConstraints(). If before SetConstraints(), the buffer collection
9180 /// won't require constraints from this node in order to allocate. If
9181 /// after SetConstraints(), the constraints are retained and aggregated
9182 /// along with any subsequent logical allocation(s), despite the lack of
9183 /// channel connection.
9184 ///
9185 /// On a BufferCollectionTokenGroup channel:
9186 ///
9187 /// By default, unexpected failure of a BufferCollectionTokenGroup will
9188 /// trigger failure of the logical BufferCollectionTokenGroup and will
9189 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
9190 /// channel without failing the logical group or propagating failure, send
9191 /// Close() before closing the channel client endpoint.
9192 ///
9193 /// If Close() occurs before AllChildrenPresent(), the logical buffer
9194 /// collection will still fail despite the Close() (because sysmem can't be
9195 /// sure whether all relevant children were created, so it's ambiguous
9196 /// whether all relevant constraints will be provided to sysmem). If
9197 /// Close() occurs after AllChildrenPresent(), the children and all their
9198 /// constraints remain intact (just as they would if the
9199 /// BufferCollectionTokenGroup channel had remained open), and the close
9200 /// doesn't trigger or propagate failure.
9201 pub fn r#close(&self) -> Result<(), fidl::Error> {
9202 NodeProxyInterface::r#close(self)
9203 }
9204
9205 /// Set a name for VMOs in this buffer collection. The name may be truncated
9206 /// shorter. The name only affects VMOs allocated after it's set - this call
9207 /// does not rename existing VMOs. If multiple clients set different names
9208 /// then the larger priority value will win.
9209 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
9210 NodeProxyInterface::r#set_name(self, priority, name)
9211 }
9212
9213 /// Set information about the current client that can be used by sysmem to
9214 /// help debug leaking memory and hangs waiting for constraints. |name| can
9215 /// be an arbitrary string, but the current process name (see
9216 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
9217 /// arbitrary id, but the current process ID (see
9218 /// fsl::GetCurrentProcessKoid()) is a good default.
9219 ///
9220 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
9221 /// indicate which client is closing their channel first, leading to
9222 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
9223 /// over, but if happening earlier than expected, the
9224 /// client-channel-specific name can help diagnose where the failure is
9225 /// first coming from, from sysmem's point of view).
9226 ///
9227 /// By default (unless overriden by this message or using
9228 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
9229 /// parent Node at the time the child Node is created. While this can be
9230 /// better than nothing, it's often better for each participant to use
9231 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
9232 /// info directly relevant to the current client. Also, SetVerboseLogging()
9233 /// can be used to help disambiguate if a Node is suspected of having info
9234 /// that was copied from its parent.
9235 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
9236 NodeProxyInterface::r#set_debug_client_info(self, name, id)
9237 }
9238
9239 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
9240 /// after creating a collection. Clients can call this method to change
9241 /// when the log is printed. If multiple client set the deadline, it's
9242 /// unspecified which deadline will take effect.
9243 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
9244 NodeProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
9245 }
9246
9247 /// Verbose logging includes constraints set via SetConstraints() from each
9248 /// client along with info set via SetDebugClientInfo() and the structure of
9249 /// the tree of Node(s).
9250 ///
9251 /// Normally sysmem prints only a single line complaint when aggregation
9252 /// fails, with just the specific detailed reason that aggregation failed,
9253 /// with minimal context. While this is often enough to diagnose a problem
9254 /// if only a small change was made and the system had been working before
9255 /// the small change, it's often not particularly helpful for getting a new
9256 /// buffer collection to work for the first time. Especially with more
9257 /// complex trees of nodes, involving things like AttachToken(),
9258 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
9259 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
9260 /// looks like and why it's failing a logical allocation, or why a tree or
9261 /// sub-tree is failing sooner than expected.
9262 ///
9263 /// The intent of the extra logging is to be acceptable from a performance
9264 /// point of view, if only enabled on a low number of buffer collections.
9265 /// If we're not tracking down a bug, we shouldn't send this message.
9266 ///
9267 /// If too many participants leave verbose logging enabled, we may end up
9268 /// needing to require that system-wide sysmem verbose logging be permitted
9269 /// via some other setting, to avoid sysmem spamming the log too much due to
9270 /// this message.
9271 ///
9272 /// This may be a NOP for some nodes due to intentional policy associated
9273 /// with the node, if we don't trust a node enough to let it turn on verbose
9274 /// logging.
9275 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
9276 NodeProxyInterface::r#set_verbose_logging(self)
9277 }
9278
9279 /// This gets an event handle that can be used as a parameter to
9280 /// IsAlternateFor() called on any Node. The client will not be granted the
9281 /// right to signal this event, as this handle should only be used as proof
9282 /// that the client obtained this handle from this Node.
9283 ///
9284 /// Because this is a get not a set, no Sync() is needed between the
9285 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
9286 /// potentially being on different channels.
9287 ///
9288 /// See also IsAlternateFor().
9289 pub fn r#get_node_ref(
9290 &self,
9291 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
9292 {
9293 NodeProxyInterface::r#get_node_ref(self)
9294 }
9295
9296 /// This checks whether the calling node is in a subtree rooted at a
9297 /// different child token of a common parent BufferCollectionTokenGroup, in
9298 /// relation to the passed-in node_ref.
9299 ///
9300 /// This call is for assisting with admission control de-duplication, and
9301 /// with debugging.
9302 ///
9303 /// The node_ref must be obtained using GetNodeRef() of a
9304 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
9305 ///
9306 /// The node_ref can be a duplicated handle; it's not necessary to call
9307 /// GetNodeRef() for every call to IsAlternateFor().
9308 ///
9309 /// If a calling token may not actually be a valid token at all due to
9310 /// a potentially hostile/untrusted provider of the token, call
9311 /// ValidateBufferCollectionToken() first instead of potentially getting
9312 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
9313 /// token not being a real token (not really talking to sysmem). Another
9314 /// option is to call BindSharedCollection with this token first which also
9315 /// validates the token along with converting it to a BufferCollection, then
9316 /// call BufferCollection IsAlternateFor().
9317 ///
9318 /// error values:
9319 ///
9320 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
9321 /// buffer collection as the calling Node. Before logical allocation and
9322 /// within the same logical allocation sub-tree, this essentially means that
9323 /// the node_ref was never part of this logical buffer collection, since
9324 /// before logical allocation all node_refs that come into existence remain
9325 /// in existence at least until logical allocation (including Node(s) that
9326 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
9327 /// to be returned, this Node's channel needs to still be connected server
9328 /// side, which won't be the case if the whole logical allocation has
9329 /// failed. After logical allocation or in a different logical allocation
9330 /// sub-tree there are additional potential reasons for this error. For
9331 /// example a different logical allocation (separated from this Node(s)
9332 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
9333 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
9334 /// exist and may select a different child sub-tree than the sub-tree the
9335 /// node_ref is in causing deletion of the node_ref Node. The only time
9336 /// sysmem keeps a Node around after that Node has no corresponding channel
9337 /// is when Close() is used and the Node's sub-tree has not yet failed.
9338 /// Another reason for this error is if the node_ref is an eventpair handle
9339 /// with sufficient rights, but isn't actually a real node_ref obtained from
9340 /// GetNodeRef().
9341 ///
9342 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
9343 /// eventpair handle, or doesn't have the needed rights expected on a real
9344 /// node_ref.
9345 ///
9346 /// No other failing status codes are returned by this call. However,
9347 /// sysmem may add additional codes in future, so the client should have
9348 /// sensible default handling for any failing status code.
9349 ///
9350 /// On success, is_alternate has the following meaning:
9351 /// * true - The first parent node in common between the calling node and
9352 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
9353 /// the calling Node and the node_ref Node will _not_ have both their
9354 /// constraints apply - rather sysmem will choose one or the other of
9355 /// the constraints - never both. This is because only one child of
9356 /// a BufferCollectionTokenGroup is selected during logical allocation,
9357 /// with only that one child's sub-tree contributing to constraints
9358 /// aggregation.
9359 /// * false - The first parent node in common between the calling Node and
9360 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
9361 /// this means the first parent node in common is a
9362 /// BufferCollectionToken or BufferCollection (regardless of not
9363 /// Close()ed or Close()ed). This means that the calling Node and the
9364 /// node_ref Node _may_ have both their constraints apply during
9365 /// constraints aggregation of the logical allocation, if both Node(s)
9366 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
9367 /// In this case, there is no BufferCollectionTokenGroup that will
9368 /// directly prevent the two Node(s) from both being selected and their
9369 /// constraints both aggregated, but even when false, one or both
9370 /// Node(s) may still be eliminated from consideration if one or both
9371 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
9372 /// which selects a child sub-tree other than the sub-tree containing
9373 /// the calling Node or node_ref Node.
9374 pub fn r#is_alternate_for(
9375 &self,
9376 mut node_ref: fidl::Event,
9377 ) -> fidl::client::QueryResponseFut<
9378 NodeIsAlternateForResult,
9379 fidl::encoding::DefaultFuchsiaResourceDialect,
9380 > {
9381 NodeProxyInterface::r#is_alternate_for(self, node_ref)
9382 }
9383}
9384
9385impl NodeProxyInterface for NodeProxy {
9386 type SyncResponseFut =
9387 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
9388 fn r#sync(&self) -> Self::SyncResponseFut {
9389 fn _decode(
9390 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9391 ) -> Result<(), fidl::Error> {
9392 let _response = fidl::client::decode_transaction_body::<
9393 fidl::encoding::EmptyPayload,
9394 fidl::encoding::DefaultFuchsiaResourceDialect,
9395 0x4577e238ae26291,
9396 >(_buf?)?;
9397 Ok(_response)
9398 }
9399 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
9400 (),
9401 0x4577e238ae26291,
9402 fidl::encoding::DynamicFlags::empty(),
9403 _decode,
9404 )
9405 }
9406
9407 fn r#close(&self) -> Result<(), fidl::Error> {
9408 self.client.send::<fidl::encoding::EmptyPayload>(
9409 (),
9410 0x5b1d7a4f5681fca7,
9411 fidl::encoding::DynamicFlags::empty(),
9412 )
9413 }
9414
9415 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
9416 self.client.send::<NodeSetNameRequest>(
9417 (priority, name),
9418 0x77a41bb6217e2443,
9419 fidl::encoding::DynamicFlags::empty(),
9420 )
9421 }
9422
9423 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
9424 self.client.send::<NodeSetDebugClientInfoRequest>(
9425 (name, id),
9426 0x7275759070eb5ee2,
9427 fidl::encoding::DynamicFlags::empty(),
9428 )
9429 }
9430
9431 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
9432 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
9433 (deadline,),
9434 0x46d38f4772638867,
9435 fidl::encoding::DynamicFlags::empty(),
9436 )
9437 }
9438
9439 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
9440 self.client.send::<fidl::encoding::EmptyPayload>(
9441 (),
9442 0x6bfbe2cf1701d288,
9443 fidl::encoding::DynamicFlags::empty(),
9444 )
9445 }
9446
9447 type GetNodeRefResponseFut =
9448 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
9449 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
9450 fn _decode(
9451 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9452 ) -> Result<fidl::Event, fidl::Error> {
9453 let _response = fidl::client::decode_transaction_body::<
9454 NodeGetNodeRefResponse,
9455 fidl::encoding::DefaultFuchsiaResourceDialect,
9456 0x467b7c75c35c3b84,
9457 >(_buf?)?;
9458 Ok(_response.node_ref)
9459 }
9460 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
9461 (),
9462 0x467b7c75c35c3b84,
9463 fidl::encoding::DynamicFlags::empty(),
9464 _decode,
9465 )
9466 }
9467
9468 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
9469 NodeIsAlternateForResult,
9470 fidl::encoding::DefaultFuchsiaResourceDialect,
9471 >;
9472 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
9473 fn _decode(
9474 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9475 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
9476 let _response = fidl::client::decode_transaction_body::<
9477 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
9478 fidl::encoding::DefaultFuchsiaResourceDialect,
9479 0x33a2a7aff2776c07,
9480 >(_buf?)?;
9481 Ok(_response.map(|x| x.is_alternate))
9482 }
9483 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
9484 (node_ref,),
9485 0x33a2a7aff2776c07,
9486 fidl::encoding::DynamicFlags::empty(),
9487 _decode,
9488 )
9489 }
9490}
9491
9492pub struct NodeEventStream {
9493 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
9494}
9495
9496impl std::marker::Unpin for NodeEventStream {}
9497
9498impl futures::stream::FusedStream for NodeEventStream {
9499 fn is_terminated(&self) -> bool {
9500 self.event_receiver.is_terminated()
9501 }
9502}
9503
9504impl futures::Stream for NodeEventStream {
9505 type Item = Result<NodeEvent, fidl::Error>;
9506
9507 fn poll_next(
9508 mut self: std::pin::Pin<&mut Self>,
9509 cx: &mut std::task::Context<'_>,
9510 ) -> std::task::Poll<Option<Self::Item>> {
9511 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
9512 &mut self.event_receiver,
9513 cx
9514 )?) {
9515 Some(buf) => std::task::Poll::Ready(Some(NodeEvent::decode(buf))),
9516 None => std::task::Poll::Ready(None),
9517 }
9518 }
9519}
9520
9521#[derive(Debug)]
9522pub enum NodeEvent {}
9523
9524impl NodeEvent {
9525 /// Decodes a message buffer as a [`NodeEvent`].
9526 fn decode(
9527 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
9528 ) -> Result<NodeEvent, fidl::Error> {
9529 let (bytes, _handles) = buf.split_mut();
9530 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
9531 debug_assert_eq!(tx_header.tx_id, 0);
9532 match tx_header.ordinal {
9533 _ => Err(fidl::Error::UnknownOrdinal {
9534 ordinal: tx_header.ordinal,
9535 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
9536 }),
9537 }
9538 }
9539}
9540
9541/// A Stream of incoming requests for fuchsia.sysmem/Node.
9542pub struct NodeRequestStream {
9543 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9544 is_terminated: bool,
9545}
9546
9547impl std::marker::Unpin for NodeRequestStream {}
9548
9549impl futures::stream::FusedStream for NodeRequestStream {
9550 fn is_terminated(&self) -> bool {
9551 self.is_terminated
9552 }
9553}
9554
9555impl fidl::endpoints::RequestStream for NodeRequestStream {
9556 type Protocol = NodeMarker;
9557 type ControlHandle = NodeControlHandle;
9558
9559 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
9560 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
9561 }
9562
9563 fn control_handle(&self) -> Self::ControlHandle {
9564 NodeControlHandle { inner: self.inner.clone() }
9565 }
9566
9567 fn into_inner(
9568 self,
9569 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
9570 {
9571 (self.inner, self.is_terminated)
9572 }
9573
9574 fn from_inner(
9575 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9576 is_terminated: bool,
9577 ) -> Self {
9578 Self { inner, is_terminated }
9579 }
9580}
9581
9582impl futures::Stream for NodeRequestStream {
9583 type Item = Result<NodeRequest, fidl::Error>;
9584
9585 fn poll_next(
9586 mut self: std::pin::Pin<&mut Self>,
9587 cx: &mut std::task::Context<'_>,
9588 ) -> std::task::Poll<Option<Self::Item>> {
9589 let this = &mut *self;
9590 if this.inner.check_shutdown(cx) {
9591 this.is_terminated = true;
9592 return std::task::Poll::Ready(None);
9593 }
9594 if this.is_terminated {
9595 panic!("polled NodeRequestStream after completion");
9596 }
9597 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
9598 |bytes, handles| {
9599 match this.inner.channel().read_etc(cx, bytes, handles) {
9600 std::task::Poll::Ready(Ok(())) => {}
9601 std::task::Poll::Pending => return std::task::Poll::Pending,
9602 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
9603 this.is_terminated = true;
9604 return std::task::Poll::Ready(None);
9605 }
9606 std::task::Poll::Ready(Err(e)) => {
9607 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
9608 e.into(),
9609 ))))
9610 }
9611 }
9612
9613 // A message has been received from the channel
9614 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
9615
9616 std::task::Poll::Ready(Some(match header.ordinal {
9617 0x4577e238ae26291 => {
9618 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9619 let mut req = fidl::new_empty!(
9620 fidl::encoding::EmptyPayload,
9621 fidl::encoding::DefaultFuchsiaResourceDialect
9622 );
9623 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9624 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9625 Ok(NodeRequest::Sync {
9626 responder: NodeSyncResponder {
9627 control_handle: std::mem::ManuallyDrop::new(control_handle),
9628 tx_id: header.tx_id,
9629 },
9630 })
9631 }
9632 0x5b1d7a4f5681fca7 => {
9633 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9634 let mut req = fidl::new_empty!(
9635 fidl::encoding::EmptyPayload,
9636 fidl::encoding::DefaultFuchsiaResourceDialect
9637 );
9638 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9639 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9640 Ok(NodeRequest::Close { control_handle })
9641 }
9642 0x77a41bb6217e2443 => {
9643 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9644 let mut req = fidl::new_empty!(
9645 NodeSetNameRequest,
9646 fidl::encoding::DefaultFuchsiaResourceDialect
9647 );
9648 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
9649 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9650 Ok(NodeRequest::SetName {
9651 priority: req.priority,
9652 name: req.name,
9653
9654 control_handle,
9655 })
9656 }
9657 0x7275759070eb5ee2 => {
9658 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9659 let mut req = fidl::new_empty!(
9660 NodeSetDebugClientInfoRequest,
9661 fidl::encoding::DefaultFuchsiaResourceDialect
9662 );
9663 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
9664 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9665 Ok(NodeRequest::SetDebugClientInfo {
9666 name: req.name,
9667 id: req.id,
9668
9669 control_handle,
9670 })
9671 }
9672 0x46d38f4772638867 => {
9673 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9674 let mut req = fidl::new_empty!(
9675 NodeSetDebugTimeoutLogDeadlineRequest,
9676 fidl::encoding::DefaultFuchsiaResourceDialect
9677 );
9678 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
9679 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9680 Ok(NodeRequest::SetDebugTimeoutLogDeadline {
9681 deadline: req.deadline,
9682
9683 control_handle,
9684 })
9685 }
9686 0x6bfbe2cf1701d288 => {
9687 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9688 let mut req = fidl::new_empty!(
9689 fidl::encoding::EmptyPayload,
9690 fidl::encoding::DefaultFuchsiaResourceDialect
9691 );
9692 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9693 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9694 Ok(NodeRequest::SetVerboseLogging { control_handle })
9695 }
9696 0x467b7c75c35c3b84 => {
9697 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9698 let mut req = fidl::new_empty!(
9699 fidl::encoding::EmptyPayload,
9700 fidl::encoding::DefaultFuchsiaResourceDialect
9701 );
9702 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9703 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9704 Ok(NodeRequest::GetNodeRef {
9705 responder: NodeGetNodeRefResponder {
9706 control_handle: std::mem::ManuallyDrop::new(control_handle),
9707 tx_id: header.tx_id,
9708 },
9709 })
9710 }
9711 0x33a2a7aff2776c07 => {
9712 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9713 let mut req = fidl::new_empty!(
9714 NodeIsAlternateForRequest,
9715 fidl::encoding::DefaultFuchsiaResourceDialect
9716 );
9717 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
9718 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9719 Ok(NodeRequest::IsAlternateFor {
9720 node_ref: req.node_ref,
9721
9722 responder: NodeIsAlternateForResponder {
9723 control_handle: std::mem::ManuallyDrop::new(control_handle),
9724 tx_id: header.tx_id,
9725 },
9726 })
9727 }
9728 _ => Err(fidl::Error::UnknownOrdinal {
9729 ordinal: header.ordinal,
9730 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
9731 }),
9732 }))
9733 },
9734 )
9735 }
9736}
9737
9738#[derive(Debug)]
9739pub enum NodeRequest {
9740 /// Ensure that previous messages, including Duplicate() messages on a
9741 /// token, collection, or group, have been received server side.
9742 ///
9743 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
9744 /// valid sysmem token risks the Sync() hanging forever. See
9745 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
9746 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
9747 /// Another way is to pass the token to BindSharedCollection(), which also
9748 /// validates the token as part of exchanging it for a BufferCollection
9749 /// channel, and BufferCollection Sync() can then be used.
9750 ///
9751 /// After a Sync(), it's then safe to send the client end of token_request
9752 /// to another participant knowing the server will recognize the token when
9753 /// it's sent into BindSharedCollection() by the other participant.
9754 ///
9755 /// Other options include waiting for each token.Duplicate() to complete
9756 /// individually (using separate call to token.Sync() after each), or
9757 /// calling Sync() on BufferCollection after the token has been turned in
9758 /// via BindSharedCollection().
9759 ///
9760 /// Another way to mitigate is to avoid calling Sync() on the token, and
9761 /// instead later deal with potential failure of BufferCollection.Sync() if
9762 /// the original token was invalid. This option can be preferable from a
9763 /// performance point of view, but requires client code to delay sending
9764 /// tokens duplicated from this token until after client code has converted
9765 /// the duplicating token to a BufferCollection and received successful
9766 /// response from BufferCollection.Sync().
9767 ///
9768 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
9769 /// When BufferCollection.Sync() isn't feasible, the caller must already
9770 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
9771 /// hang forever. See ValidateBufferCollectionToken() to check token
9772 /// validity first if the token isn't already known to be (is/was) valid.
9773 Sync { responder: NodeSyncResponder },
9774 /// On a BufferCollectionToken channel:
9775 ///
9776 /// Normally a participant will convert a BufferCollectionToken into a
9777 /// BufferCollection view, but a participant is also free to Close() the
9778 /// token (and then close the channel immediately or shortly later in
9779 /// response to server closing its end), which avoids causing logical buffer
9780 /// collection failure. Â Normally an unexpected token channel close will
9781 /// cause logical buffer collection failure (the only exceptions being
9782 /// certain cases involving AttachToken() or SetDispensable()).
9783 ///
9784 /// On a BufferCollection channel:
9785 ///
9786 /// By default the server handles unexpected failure of a BufferCollection
9787 /// by failing the whole logical buffer collection. Partly this is to
9788 /// expedite closing VMO handles to reclaim memory when any participant
9789 /// fails. If a participant would like to cleanly close a BufferCollection
9790 /// view without causing logical buffer collection failure, the participant
9791 /// can send Close() before closing the client end of the BufferCollection
9792 /// channel. If this is the last BufferCollection view, the logical buffer
9793 /// collection will still go away. The Close() can occur before or after
9794 /// SetConstraints(). If before SetConstraints(), the buffer collection
9795 /// won't require constraints from this node in order to allocate. If
9796 /// after SetConstraints(), the constraints are retained and aggregated
9797 /// along with any subsequent logical allocation(s), despite the lack of
9798 /// channel connection.
9799 ///
9800 /// On a BufferCollectionTokenGroup channel:
9801 ///
9802 /// By default, unexpected failure of a BufferCollectionTokenGroup will
9803 /// trigger failure of the logical BufferCollectionTokenGroup and will
9804 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
9805 /// channel without failing the logical group or propagating failure, send
9806 /// Close() before closing the channel client endpoint.
9807 ///
9808 /// If Close() occurs before AllChildrenPresent(), the logical buffer
9809 /// collection will still fail despite the Close() (because sysmem can't be
9810 /// sure whether all relevant children were created, so it's ambiguous
9811 /// whether all relevant constraints will be provided to sysmem). If
9812 /// Close() occurs after AllChildrenPresent(), the children and all their
9813 /// constraints remain intact (just as they would if the
9814 /// BufferCollectionTokenGroup channel had remained open), and the close
9815 /// doesn't trigger or propagate failure.
9816 Close { control_handle: NodeControlHandle },
9817 /// Set a name for VMOs in this buffer collection. The name may be truncated
9818 /// shorter. The name only affects VMOs allocated after it's set - this call
9819 /// does not rename existing VMOs. If multiple clients set different names
9820 /// then the larger priority value will win.
9821 SetName { priority: u32, name: String, control_handle: NodeControlHandle },
9822 /// Set information about the current client that can be used by sysmem to
9823 /// help debug leaking memory and hangs waiting for constraints. |name| can
9824 /// be an arbitrary string, but the current process name (see
9825 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
9826 /// arbitrary id, but the current process ID (see
9827 /// fsl::GetCurrentProcessKoid()) is a good default.
9828 ///
9829 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
9830 /// indicate which client is closing their channel first, leading to
9831 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
9832 /// over, but if happening earlier than expected, the
9833 /// client-channel-specific name can help diagnose where the failure is
9834 /// first coming from, from sysmem's point of view).
9835 ///
9836 /// By default (unless overriden by this message or using
9837 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
9838 /// parent Node at the time the child Node is created. While this can be
9839 /// better than nothing, it's often better for each participant to use
9840 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
9841 /// info directly relevant to the current client. Also, SetVerboseLogging()
9842 /// can be used to help disambiguate if a Node is suspected of having info
9843 /// that was copied from its parent.
9844 SetDebugClientInfo { name: String, id: u64, control_handle: NodeControlHandle },
9845 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
9846 /// after creating a collection. Clients can call this method to change
9847 /// when the log is printed. If multiple client set the deadline, it's
9848 /// unspecified which deadline will take effect.
9849 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: NodeControlHandle },
9850 /// Verbose logging includes constraints set via SetConstraints() from each
9851 /// client along with info set via SetDebugClientInfo() and the structure of
9852 /// the tree of Node(s).
9853 ///
9854 /// Normally sysmem prints only a single line complaint when aggregation
9855 /// fails, with just the specific detailed reason that aggregation failed,
9856 /// with minimal context. While this is often enough to diagnose a problem
9857 /// if only a small change was made and the system had been working before
9858 /// the small change, it's often not particularly helpful for getting a new
9859 /// buffer collection to work for the first time. Especially with more
9860 /// complex trees of nodes, involving things like AttachToken(),
9861 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
9862 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
9863 /// looks like and why it's failing a logical allocation, or why a tree or
9864 /// sub-tree is failing sooner than expected.
9865 ///
9866 /// The intent of the extra logging is to be acceptable from a performance
9867 /// point of view, if only enabled on a low number of buffer collections.
9868 /// If we're not tracking down a bug, we shouldn't send this message.
9869 ///
9870 /// If too many participants leave verbose logging enabled, we may end up
9871 /// needing to require that system-wide sysmem verbose logging be permitted
9872 /// via some other setting, to avoid sysmem spamming the log too much due to
9873 /// this message.
9874 ///
9875 /// This may be a NOP for some nodes due to intentional policy associated
9876 /// with the node, if we don't trust a node enough to let it turn on verbose
9877 /// logging.
9878 SetVerboseLogging { control_handle: NodeControlHandle },
9879 /// This gets an event handle that can be used as a parameter to
9880 /// IsAlternateFor() called on any Node. The client will not be granted the
9881 /// right to signal this event, as this handle should only be used as proof
9882 /// that the client obtained this handle from this Node.
9883 ///
9884 /// Because this is a get not a set, no Sync() is needed between the
9885 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
9886 /// potentially being on different channels.
9887 ///
9888 /// See also IsAlternateFor().
9889 GetNodeRef { responder: NodeGetNodeRefResponder },
9890 /// This checks whether the calling node is in a subtree rooted at a
9891 /// different child token of a common parent BufferCollectionTokenGroup, in
9892 /// relation to the passed-in node_ref.
9893 ///
9894 /// This call is for assisting with admission control de-duplication, and
9895 /// with debugging.
9896 ///
9897 /// The node_ref must be obtained using GetNodeRef() of a
9898 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
9899 ///
9900 /// The node_ref can be a duplicated handle; it's not necessary to call
9901 /// GetNodeRef() for every call to IsAlternateFor().
9902 ///
9903 /// If a calling token may not actually be a valid token at all due to
9904 /// a potentially hostile/untrusted provider of the token, call
9905 /// ValidateBufferCollectionToken() first instead of potentially getting
9906 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
9907 /// token not being a real token (not really talking to sysmem). Another
9908 /// option is to call BindSharedCollection with this token first which also
9909 /// validates the token along with converting it to a BufferCollection, then
9910 /// call BufferCollection IsAlternateFor().
9911 ///
9912 /// error values:
9913 ///
9914 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
9915 /// buffer collection as the calling Node. Before logical allocation and
9916 /// within the same logical allocation sub-tree, this essentially means that
9917 /// the node_ref was never part of this logical buffer collection, since
9918 /// before logical allocation all node_refs that come into existence remain
9919 /// in existence at least until logical allocation (including Node(s) that
9920 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
9921 /// to be returned, this Node's channel needs to still be connected server
9922 /// side, which won't be the case if the whole logical allocation has
9923 /// failed. After logical allocation or in a different logical allocation
9924 /// sub-tree there are additional potential reasons for this error. For
9925 /// example a different logical allocation (separated from this Node(s)
9926 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
9927 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
9928 /// exist and may select a different child sub-tree than the sub-tree the
9929 /// node_ref is in causing deletion of the node_ref Node. The only time
9930 /// sysmem keeps a Node around after that Node has no corresponding channel
9931 /// is when Close() is used and the Node's sub-tree has not yet failed.
9932 /// Another reason for this error is if the node_ref is an eventpair handle
9933 /// with sufficient rights, but isn't actually a real node_ref obtained from
9934 /// GetNodeRef().
9935 ///
9936 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
9937 /// eventpair handle, or doesn't have the needed rights expected on a real
9938 /// node_ref.
9939 ///
9940 /// No other failing status codes are returned by this call. However,
9941 /// sysmem may add additional codes in future, so the client should have
9942 /// sensible default handling for any failing status code.
9943 ///
9944 /// On success, is_alternate has the following meaning:
9945 /// * true - The first parent node in common between the calling node and
9946 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
9947 /// the calling Node and the node_ref Node will _not_ have both their
9948 /// constraints apply - rather sysmem will choose one or the other of
9949 /// the constraints - never both. This is because only one child of
9950 /// a BufferCollectionTokenGroup is selected during logical allocation,
9951 /// with only that one child's sub-tree contributing to constraints
9952 /// aggregation.
9953 /// * false - The first parent node in common between the calling Node and
9954 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
9955 /// this means the first parent node in common is a
9956 /// BufferCollectionToken or BufferCollection (regardless of not
9957 /// Close()ed or Close()ed). This means that the calling Node and the
9958 /// node_ref Node _may_ have both their constraints apply during
9959 /// constraints aggregation of the logical allocation, if both Node(s)
9960 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
9961 /// In this case, there is no BufferCollectionTokenGroup that will
9962 /// directly prevent the two Node(s) from both being selected and their
9963 /// constraints both aggregated, but even when false, one or both
9964 /// Node(s) may still be eliminated from consideration if one or both
9965 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
9966 /// which selects a child sub-tree other than the sub-tree containing
9967 /// the calling Node or node_ref Node.
9968 IsAlternateFor { node_ref: fidl::Event, responder: NodeIsAlternateForResponder },
9969}
9970
9971impl NodeRequest {
9972 #[allow(irrefutable_let_patterns)]
9973 pub fn into_sync(self) -> Option<(NodeSyncResponder)> {
9974 if let NodeRequest::Sync { responder } = self {
9975 Some((responder))
9976 } else {
9977 None
9978 }
9979 }
9980
9981 #[allow(irrefutable_let_patterns)]
9982 pub fn into_close(self) -> Option<(NodeControlHandle)> {
9983 if let NodeRequest::Close { control_handle } = self {
9984 Some((control_handle))
9985 } else {
9986 None
9987 }
9988 }
9989
9990 #[allow(irrefutable_let_patterns)]
9991 pub fn into_set_name(self) -> Option<(u32, String, NodeControlHandle)> {
9992 if let NodeRequest::SetName { priority, name, control_handle } = self {
9993 Some((priority, name, control_handle))
9994 } else {
9995 None
9996 }
9997 }
9998
9999 #[allow(irrefutable_let_patterns)]
10000 pub fn into_set_debug_client_info(self) -> Option<(String, u64, NodeControlHandle)> {
10001 if let NodeRequest::SetDebugClientInfo { name, id, control_handle } = self {
10002 Some((name, id, control_handle))
10003 } else {
10004 None
10005 }
10006 }
10007
10008 #[allow(irrefutable_let_patterns)]
10009 pub fn into_set_debug_timeout_log_deadline(self) -> Option<(i64, NodeControlHandle)> {
10010 if let NodeRequest::SetDebugTimeoutLogDeadline { deadline, control_handle } = self {
10011 Some((deadline, control_handle))
10012 } else {
10013 None
10014 }
10015 }
10016
10017 #[allow(irrefutable_let_patterns)]
10018 pub fn into_set_verbose_logging(self) -> Option<(NodeControlHandle)> {
10019 if let NodeRequest::SetVerboseLogging { control_handle } = self {
10020 Some((control_handle))
10021 } else {
10022 None
10023 }
10024 }
10025
10026 #[allow(irrefutable_let_patterns)]
10027 pub fn into_get_node_ref(self) -> Option<(NodeGetNodeRefResponder)> {
10028 if let NodeRequest::GetNodeRef { responder } = self {
10029 Some((responder))
10030 } else {
10031 None
10032 }
10033 }
10034
10035 #[allow(irrefutable_let_patterns)]
10036 pub fn into_is_alternate_for(self) -> Option<(fidl::Event, NodeIsAlternateForResponder)> {
10037 if let NodeRequest::IsAlternateFor { node_ref, responder } = self {
10038 Some((node_ref, responder))
10039 } else {
10040 None
10041 }
10042 }
10043
10044 /// Name of the method defined in FIDL
10045 pub fn method_name(&self) -> &'static str {
10046 match *self {
10047 NodeRequest::Sync { .. } => "sync",
10048 NodeRequest::Close { .. } => "close",
10049 NodeRequest::SetName { .. } => "set_name",
10050 NodeRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
10051 NodeRequest::SetDebugTimeoutLogDeadline { .. } => "set_debug_timeout_log_deadline",
10052 NodeRequest::SetVerboseLogging { .. } => "set_verbose_logging",
10053 NodeRequest::GetNodeRef { .. } => "get_node_ref",
10054 NodeRequest::IsAlternateFor { .. } => "is_alternate_for",
10055 }
10056 }
10057}
10058
10059#[derive(Debug, Clone)]
10060pub struct NodeControlHandle {
10061 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
10062}
10063
10064impl fidl::endpoints::ControlHandle for NodeControlHandle {
10065 fn shutdown(&self) {
10066 self.inner.shutdown()
10067 }
10068 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
10069 self.inner.shutdown_with_epitaph(status)
10070 }
10071
10072 fn is_closed(&self) -> bool {
10073 self.inner.channel().is_closed()
10074 }
10075 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
10076 self.inner.channel().on_closed()
10077 }
10078
10079 #[cfg(target_os = "fuchsia")]
10080 fn signal_peer(
10081 &self,
10082 clear_mask: zx::Signals,
10083 set_mask: zx::Signals,
10084 ) -> Result<(), zx_status::Status> {
10085 use fidl::Peered;
10086 self.inner.channel().signal_peer(clear_mask, set_mask)
10087 }
10088}
10089
10090impl NodeControlHandle {}
10091
10092#[must_use = "FIDL methods require a response to be sent"]
10093#[derive(Debug)]
10094pub struct NodeSyncResponder {
10095 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
10096 tx_id: u32,
10097}
10098
10099/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
10100/// if the responder is dropped without sending a response, so that the client
10101/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
10102impl std::ops::Drop for NodeSyncResponder {
10103 fn drop(&mut self) {
10104 self.control_handle.shutdown();
10105 // Safety: drops once, never accessed again
10106 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10107 }
10108}
10109
10110impl fidl::endpoints::Responder for NodeSyncResponder {
10111 type ControlHandle = NodeControlHandle;
10112
10113 fn control_handle(&self) -> &NodeControlHandle {
10114 &self.control_handle
10115 }
10116
10117 fn drop_without_shutdown(mut self) {
10118 // Safety: drops once, never accessed again due to mem::forget
10119 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10120 // Prevent Drop from running (which would shut down the channel)
10121 std::mem::forget(self);
10122 }
10123}
10124
10125impl NodeSyncResponder {
10126 /// Sends a response to the FIDL transaction.
10127 ///
10128 /// Sets the channel to shutdown if an error occurs.
10129 pub fn send(self) -> Result<(), fidl::Error> {
10130 let _result = self.send_raw();
10131 if _result.is_err() {
10132 self.control_handle.shutdown();
10133 }
10134 self.drop_without_shutdown();
10135 _result
10136 }
10137
10138 /// Similar to "send" but does not shutdown the channel if an error occurs.
10139 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
10140 let _result = self.send_raw();
10141 self.drop_without_shutdown();
10142 _result
10143 }
10144
10145 fn send_raw(&self) -> Result<(), fidl::Error> {
10146 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
10147 (),
10148 self.tx_id,
10149 0x4577e238ae26291,
10150 fidl::encoding::DynamicFlags::empty(),
10151 )
10152 }
10153}
10154
10155#[must_use = "FIDL methods require a response to be sent"]
10156#[derive(Debug)]
10157pub struct NodeGetNodeRefResponder {
10158 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
10159 tx_id: u32,
10160}
10161
10162/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
10163/// if the responder is dropped without sending a response, so that the client
10164/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
10165impl std::ops::Drop for NodeGetNodeRefResponder {
10166 fn drop(&mut self) {
10167 self.control_handle.shutdown();
10168 // Safety: drops once, never accessed again
10169 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10170 }
10171}
10172
10173impl fidl::endpoints::Responder for NodeGetNodeRefResponder {
10174 type ControlHandle = NodeControlHandle;
10175
10176 fn control_handle(&self) -> &NodeControlHandle {
10177 &self.control_handle
10178 }
10179
10180 fn drop_without_shutdown(mut self) {
10181 // Safety: drops once, never accessed again due to mem::forget
10182 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10183 // Prevent Drop from running (which would shut down the channel)
10184 std::mem::forget(self);
10185 }
10186}
10187
10188impl NodeGetNodeRefResponder {
10189 /// Sends a response to the FIDL transaction.
10190 ///
10191 /// Sets the channel to shutdown if an error occurs.
10192 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10193 let _result = self.send_raw(node_ref);
10194 if _result.is_err() {
10195 self.control_handle.shutdown();
10196 }
10197 self.drop_without_shutdown();
10198 _result
10199 }
10200
10201 /// Similar to "send" but does not shutdown the channel if an error occurs.
10202 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10203 let _result = self.send_raw(node_ref);
10204 self.drop_without_shutdown();
10205 _result
10206 }
10207
10208 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10209 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
10210 (node_ref,),
10211 self.tx_id,
10212 0x467b7c75c35c3b84,
10213 fidl::encoding::DynamicFlags::empty(),
10214 )
10215 }
10216}
10217
10218#[must_use = "FIDL methods require a response to be sent"]
10219#[derive(Debug)]
10220pub struct NodeIsAlternateForResponder {
10221 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
10222 tx_id: u32,
10223}
10224
10225/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
10226/// if the responder is dropped without sending a response, so that the client
10227/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
10228impl std::ops::Drop for NodeIsAlternateForResponder {
10229 fn drop(&mut self) {
10230 self.control_handle.shutdown();
10231 // Safety: drops once, never accessed again
10232 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10233 }
10234}
10235
10236impl fidl::endpoints::Responder for NodeIsAlternateForResponder {
10237 type ControlHandle = NodeControlHandle;
10238
10239 fn control_handle(&self) -> &NodeControlHandle {
10240 &self.control_handle
10241 }
10242
10243 fn drop_without_shutdown(mut self) {
10244 // Safety: drops once, never accessed again due to mem::forget
10245 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10246 // Prevent Drop from running (which would shut down the channel)
10247 std::mem::forget(self);
10248 }
10249}
10250
10251impl NodeIsAlternateForResponder {
10252 /// Sends a response to the FIDL transaction.
10253 ///
10254 /// Sets the channel to shutdown if an error occurs.
10255 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10256 let _result = self.send_raw(result);
10257 if _result.is_err() {
10258 self.control_handle.shutdown();
10259 }
10260 self.drop_without_shutdown();
10261 _result
10262 }
10263
10264 /// Similar to "send" but does not shutdown the channel if an error occurs.
10265 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10266 let _result = self.send_raw(result);
10267 self.drop_without_shutdown();
10268 _result
10269 }
10270
10271 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10272 self.control_handle
10273 .inner
10274 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
10275 result.map(|is_alternate| (is_alternate,)),
10276 self.tx_id,
10277 0x33a2a7aff2776c07,
10278 fidl::encoding::DynamicFlags::empty(),
10279 )
10280 }
10281}
10282
10283#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
10284pub struct SecureMemMarker;
10285
10286impl fidl::endpoints::ProtocolMarker for SecureMemMarker {
10287 type Proxy = SecureMemProxy;
10288 type RequestStream = SecureMemRequestStream;
10289 #[cfg(target_os = "fuchsia")]
10290 type SynchronousProxy = SecureMemSynchronousProxy;
10291
10292 const DEBUG_NAME: &'static str = "(anonymous) SecureMem";
10293}
10294pub type SecureMemGetPhysicalSecureHeapsResult = Result<SecureHeapsAndRanges, i32>;
10295pub type SecureMemGetPhysicalSecureHeapPropertiesResult = Result<SecureHeapProperties, i32>;
10296pub type SecureMemAddSecureHeapPhysicalRangeResult = Result<(), i32>;
10297pub type SecureMemDeleteSecureHeapPhysicalRangeResult = Result<(), i32>;
10298pub type SecureMemModifySecureHeapPhysicalRangeResult = Result<(), i32>;
10299pub type SecureMemZeroSubRangeResult = Result<(), i32>;
10300
10301pub trait SecureMemProxyInterface: Send + Sync {
10302 type GetPhysicalSecureHeapsResponseFut: std::future::Future<Output = Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error>>
10303 + Send;
10304 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut;
10305 type GetPhysicalSecureHeapPropertiesResponseFut: std::future::Future<
10306 Output = Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error>,
10307 > + Send;
10308 fn r#get_physical_secure_heap_properties(
10309 &self,
10310 entire_heap: &SecureHeapAndRange,
10311 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut;
10312 type AddSecureHeapPhysicalRangeResponseFut: std::future::Future<Output = Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error>>
10313 + Send;
10314 fn r#add_secure_heap_physical_range(
10315 &self,
10316 heap_range: &SecureHeapAndRange,
10317 ) -> Self::AddSecureHeapPhysicalRangeResponseFut;
10318 type DeleteSecureHeapPhysicalRangeResponseFut: std::future::Future<
10319 Output = Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error>,
10320 > + Send;
10321 fn r#delete_secure_heap_physical_range(
10322 &self,
10323 heap_range: &SecureHeapAndRange,
10324 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut;
10325 type ModifySecureHeapPhysicalRangeResponseFut: std::future::Future<
10326 Output = Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error>,
10327 > + Send;
10328 fn r#modify_secure_heap_physical_range(
10329 &self,
10330 range_modification: &SecureHeapAndRangeModification,
10331 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut;
10332 type ZeroSubRangeResponseFut: std::future::Future<Output = Result<SecureMemZeroSubRangeResult, fidl::Error>>
10333 + Send;
10334 fn r#zero_sub_range(
10335 &self,
10336 is_covering_range_explicit: bool,
10337 heap_range: &SecureHeapAndRange,
10338 ) -> Self::ZeroSubRangeResponseFut;
10339}
10340#[derive(Debug)]
10341#[cfg(target_os = "fuchsia")]
10342pub struct SecureMemSynchronousProxy {
10343 client: fidl::client::sync::Client,
10344}
10345
10346#[cfg(target_os = "fuchsia")]
10347impl fidl::endpoints::SynchronousProxy for SecureMemSynchronousProxy {
10348 type Proxy = SecureMemProxy;
10349 type Protocol = SecureMemMarker;
10350
10351 fn from_channel(inner: fidl::Channel) -> Self {
10352 Self::new(inner)
10353 }
10354
10355 fn into_channel(self) -> fidl::Channel {
10356 self.client.into_channel()
10357 }
10358
10359 fn as_channel(&self) -> &fidl::Channel {
10360 self.client.as_channel()
10361 }
10362}
10363
10364#[cfg(target_os = "fuchsia")]
10365impl SecureMemSynchronousProxy {
10366 pub fn new(channel: fidl::Channel) -> Self {
10367 let protocol_name = <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
10368 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
10369 }
10370
10371 pub fn into_channel(self) -> fidl::Channel {
10372 self.client.into_channel()
10373 }
10374
10375 /// Waits until an event arrives and returns it. It is safe for other
10376 /// threads to make concurrent requests while waiting for an event.
10377 pub fn wait_for_event(
10378 &self,
10379 deadline: zx::MonotonicInstant,
10380 ) -> Result<SecureMemEvent, fidl::Error> {
10381 SecureMemEvent::decode(self.client.wait_for_event(deadline)?)
10382 }
10383
10384 /// Gets the physical address and length of any secure heap whose physical
10385 /// range is configured via the TEE.
10386 ///
10387 /// Presently, these will be fixed physical addresses and lengths, with the
10388 /// location plumbed via the TEE.
10389 ///
10390 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
10391 /// when there isn't any special heap-specific per-VMO setup or teardown
10392 /// required.
10393 ///
10394 /// The physical range must be secured/protected by the TEE before the
10395 /// securemem driver responds to this request with success.
10396 ///
10397 /// Sysmem should only call this once. Returning zero heaps is not a
10398 /// failure.
10399 ///
10400 /// Errors:
10401 /// * ZX_ERR_BAD_STATE - called more than once.
10402 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10403 /// with TEE which doesn't generate zx_status_t errors).
10404 /// * other errors are allowed; any other errors should be treated the same
10405 /// as ZX_ERR_INTERNAL.
10406 pub fn r#get_physical_secure_heaps(
10407 &self,
10408 ___deadline: zx::MonotonicInstant,
10409 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
10410 let _response = self.client.send_query::<
10411 fidl::encoding::EmptyPayload,
10412 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapsResponse, i32>,
10413 >(
10414 (),
10415 0x782319d6ce7fa05,
10416 fidl::encoding::DynamicFlags::empty(),
10417 ___deadline,
10418 )?;
10419 Ok(_response.map(|x| x.heaps))
10420 }
10421
10422 /// This request from sysmem to the securemem driver gets the properties of
10423 /// a protected/secure heap.
10424 ///
10425 /// This only handles heaps with a single contiguous physical extent.
10426 ///
10427 /// The heap's entire physical range is indicated in case this request needs
10428 /// some physical space to auto-detect how many ranges are REE-usable. Any
10429 /// temporary HW protection ranges will be deleted before this request
10430 /// completes.
10431 pub fn r#get_physical_secure_heap_properties(
10432 &self,
10433 mut entire_heap: &SecureHeapAndRange,
10434 ___deadline: zx::MonotonicInstant,
10435 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
10436 let _response = self.client.send_query::<
10437 SecureMemGetPhysicalSecureHeapPropertiesRequest,
10438 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapPropertiesResponse, i32>,
10439 >(
10440 (entire_heap,),
10441 0x26404e23f1271214,
10442 fidl::encoding::DynamicFlags::empty(),
10443 ___deadline,
10444 )?;
10445 Ok(_response.map(|x| x.properties))
10446 }
10447
10448 /// This request from sysmem to the securemem driver conveys a physical
10449 /// range to add, for a heap whose physical range(s) are set up via
10450 /// sysmem.
10451 ///
10452 /// Only sysmem can call this because only sysmem is handed the client end
10453 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10454 /// securemem driver is the server end of this protocol.
10455 ///
10456 /// The securemem driver must configure all the covered offsets as protected
10457 /// before responding to this message with success.
10458 ///
10459 /// On failure, the securemem driver must ensure the protected range was not
10460 /// created.
10461 ///
10462 /// Sysmem must only call this up to once if dynamic_protection_ranges
10463 /// false.
10464 ///
10465 /// If dynamic_protection_ranges is true, sysmem can call this multiple
10466 /// times as long as the current number of ranges never exceeds
10467 /// max_protected_range_count.
10468 ///
10469 /// The caller must not attempt to add a range that matches an
10470 /// already-existing range. Added ranges can overlap each other as long as
10471 /// no two ranges match exactly.
10472 ///
10473 /// Errors:
10474 /// * ZX_ERR_BAD_STATE - called more than once when
10475 /// !dynamic_protection_ranges. Adding a heap that would cause overall
10476 /// heap count to exceed max_protected_range_count.
10477 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10478 /// to protected_range_granularity.
10479 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10480 /// with TEE which doesn't generate zx_status_t errors).
10481 /// * other errors are possible, such as from communication failures or
10482 /// server propagation of zx_status_t failures.
10483 pub fn r#add_secure_heap_physical_range(
10484 &self,
10485 mut heap_range: &SecureHeapAndRange,
10486 ___deadline: zx::MonotonicInstant,
10487 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
10488 let _response = self.client.send_query::<
10489 SecureMemAddSecureHeapPhysicalRangeRequest,
10490 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10491 >(
10492 (heap_range,),
10493 0x1ca1abcee8a0b33e,
10494 fidl::encoding::DynamicFlags::empty(),
10495 ___deadline,
10496 )?;
10497 Ok(_response.map(|x| x))
10498 }
10499
10500 /// This request from sysmem to the securemem driver conveys a physical
10501 /// range to delete, for a heap whose physical range(s) are set up via
10502 /// sysmem.
10503 ///
10504 /// Only sysmem can call this because only sysmem is handed the client end
10505 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10506 /// securemem driver is the server end of this protocol.
10507 ///
10508 /// The securemem driver must configure all the covered offsets as not
10509 /// protected before responding to this message with success.
10510 ///
10511 /// On failure, the securemem driver must ensure the protected range was not
10512 /// deleted.
10513 ///
10514 /// Sysmem must not call this if dynamic_protection_ranges false.
10515 ///
10516 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10517 /// on various ranges that exist at the time of the call.
10518 ///
10519 /// If any portion of the range being deleted is not also covered by another
10520 /// protected range, then any ongoing DMA to any part of the entire range
10521 /// may be interrupted / may fail, potentially in a way that's disruptive to
10522 /// the entire system (bus lockup or similar, depending on device details).
10523 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
10524 /// any portion of the range being deleted, unless the caller has other
10525 /// active ranges covering every block of the range being deleted. Ongoing
10526 /// DMA to/from blocks outside the range being deleted is never impacted by
10527 /// the deletion.
10528 ///
10529 /// Errors:
10530 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10531 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10532 /// to protected_range_granularity.
10533 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10534 /// with TEE which doesn't generate zx_status_t errors).
10535 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10536 /// * other errors are possible, such as from communication failures or
10537 /// server propagation of zx_status_t failures.
10538 pub fn r#delete_secure_heap_physical_range(
10539 &self,
10540 mut heap_range: &SecureHeapAndRange,
10541 ___deadline: zx::MonotonicInstant,
10542 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
10543 let _response = self.client.send_query::<
10544 SecureMemDeleteSecureHeapPhysicalRangeRequest,
10545 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10546 >(
10547 (heap_range,),
10548 0x728a953e56df92ee,
10549 fidl::encoding::DynamicFlags::empty(),
10550 ___deadline,
10551 )?;
10552 Ok(_response.map(|x| x))
10553 }
10554
10555 /// This request from sysmem to the securemem driver conveys a physical
10556 /// range to modify and its new base and length, for a heap whose physical
10557 /// range(s) are set up via sysmem.
10558 ///
10559 /// Only sysmem can call this because only sysmem is handed the client end
10560 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10561 /// securemem driver is the server end of this protocol.
10562 ///
10563 /// The securemem driver must configure the range to cover only the new
10564 /// offsets before responding to this message with success.
10565 ///
10566 /// On failure, the securemem driver must ensure the range was not changed.
10567 ///
10568 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
10569 /// must not call this if !is_mod_protected_range_available.
10570 ///
10571 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10572 /// on various ranges that exist at the time of the call.
10573 ///
10574 /// The range must only be modified at one end or the other, but not both.
10575 /// If the range is getting shorter, and the un-covered blocks are not
10576 /// covered by other active ranges, any ongoing DMA to the entire range
10577 /// that's geting shorter may fail in a way that disrupts the entire system
10578 /// (bus lockup or similar), so the caller must ensure that no DMA is
10579 /// ongoing to any portion of a range that is getting shorter, unless the
10580 /// blocks being un-covered by the modification to this range are all
10581 /// covered by other active ranges, in which case no disruption to ongoing
10582 /// DMA will occur.
10583 ///
10584 /// If a range is modified to become <= zero length, the range is deleted.
10585 ///
10586 /// Errors:
10587 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10588 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
10589 /// that doesn't conform to protected_range_granularity, or old_range
10590 /// and new_range differ in both begin and end (disallowed).
10591 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10592 /// with TEE which doesn't generate zx_status_t errors).
10593 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10594 /// * other errors are possible, such as from communication failures or
10595 /// server propagation of zx_status_t failures.
10596 pub fn r#modify_secure_heap_physical_range(
10597 &self,
10598 mut range_modification: &SecureHeapAndRangeModification,
10599 ___deadline: zx::MonotonicInstant,
10600 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
10601 let _response = self.client.send_query::<
10602 SecureMemModifySecureHeapPhysicalRangeRequest,
10603 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10604 >(
10605 (range_modification,),
10606 0x154fbfa3646a890d,
10607 fidl::encoding::DynamicFlags::empty(),
10608 ___deadline,
10609 )?;
10610 Ok(_response.map(|x| x))
10611 }
10612
10613 /// Zero a sub-range of a currently-existing physical range added via
10614 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
10615 /// exactly one physical range, and must not overlap with any other
10616 /// physical range.
10617 ///
10618 /// is_covering_range_explicit - When true, the covering range must be one
10619 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
10620 /// possibly modified since. When false, the covering range must not
10621 /// be one of the ranges explicitly created via
10622 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
10623 /// a covering range not created via AddSecureHeapPhysicalRange(). The
10624 /// covering range is typically the entire physical range (or a range
10625 /// which covers even more) of a heap configured by the TEE and whose
10626 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
10627 ///
10628 /// Ongoing DMA is not disrupted by this request.
10629 pub fn r#zero_sub_range(
10630 &self,
10631 mut is_covering_range_explicit: bool,
10632 mut heap_range: &SecureHeapAndRange,
10633 ___deadline: zx::MonotonicInstant,
10634 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
10635 let _response = self.client.send_query::<
10636 SecureMemZeroSubRangeRequest,
10637 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10638 >(
10639 (is_covering_range_explicit, heap_range,),
10640 0x7480f72bb5bc7e5b,
10641 fidl::encoding::DynamicFlags::empty(),
10642 ___deadline,
10643 )?;
10644 Ok(_response.map(|x| x))
10645 }
10646}
10647
10648#[derive(Debug, Clone)]
10649pub struct SecureMemProxy {
10650 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
10651}
10652
10653impl fidl::endpoints::Proxy for SecureMemProxy {
10654 type Protocol = SecureMemMarker;
10655
10656 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
10657 Self::new(inner)
10658 }
10659
10660 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
10661 self.client.into_channel().map_err(|client| Self { client })
10662 }
10663
10664 fn as_channel(&self) -> &::fidl::AsyncChannel {
10665 self.client.as_channel()
10666 }
10667}
10668
10669impl SecureMemProxy {
10670 /// Create a new Proxy for fuchsia.sysmem/SecureMem.
10671 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
10672 let protocol_name = <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
10673 Self { client: fidl::client::Client::new(channel, protocol_name) }
10674 }
10675
10676 /// Get a Stream of events from the remote end of the protocol.
10677 ///
10678 /// # Panics
10679 ///
10680 /// Panics if the event stream was already taken.
10681 pub fn take_event_stream(&self) -> SecureMemEventStream {
10682 SecureMemEventStream { event_receiver: self.client.take_event_receiver() }
10683 }
10684
10685 /// Gets the physical address and length of any secure heap whose physical
10686 /// range is configured via the TEE.
10687 ///
10688 /// Presently, these will be fixed physical addresses and lengths, with the
10689 /// location plumbed via the TEE.
10690 ///
10691 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
10692 /// when there isn't any special heap-specific per-VMO setup or teardown
10693 /// required.
10694 ///
10695 /// The physical range must be secured/protected by the TEE before the
10696 /// securemem driver responds to this request with success.
10697 ///
10698 /// Sysmem should only call this once. Returning zero heaps is not a
10699 /// failure.
10700 ///
10701 /// Errors:
10702 /// * ZX_ERR_BAD_STATE - called more than once.
10703 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10704 /// with TEE which doesn't generate zx_status_t errors).
10705 /// * other errors are allowed; any other errors should be treated the same
10706 /// as ZX_ERR_INTERNAL.
10707 pub fn r#get_physical_secure_heaps(
10708 &self,
10709 ) -> fidl::client::QueryResponseFut<
10710 SecureMemGetPhysicalSecureHeapsResult,
10711 fidl::encoding::DefaultFuchsiaResourceDialect,
10712 > {
10713 SecureMemProxyInterface::r#get_physical_secure_heaps(self)
10714 }
10715
10716 /// This request from sysmem to the securemem driver gets the properties of
10717 /// a protected/secure heap.
10718 ///
10719 /// This only handles heaps with a single contiguous physical extent.
10720 ///
10721 /// The heap's entire physical range is indicated in case this request needs
10722 /// some physical space to auto-detect how many ranges are REE-usable. Any
10723 /// temporary HW protection ranges will be deleted before this request
10724 /// completes.
10725 pub fn r#get_physical_secure_heap_properties(
10726 &self,
10727 mut entire_heap: &SecureHeapAndRange,
10728 ) -> fidl::client::QueryResponseFut<
10729 SecureMemGetPhysicalSecureHeapPropertiesResult,
10730 fidl::encoding::DefaultFuchsiaResourceDialect,
10731 > {
10732 SecureMemProxyInterface::r#get_physical_secure_heap_properties(self, entire_heap)
10733 }
10734
10735 /// This request from sysmem to the securemem driver conveys a physical
10736 /// range to add, for a heap whose physical range(s) are set up via
10737 /// sysmem.
10738 ///
10739 /// Only sysmem can call this because only sysmem is handed the client end
10740 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10741 /// securemem driver is the server end of this protocol.
10742 ///
10743 /// The securemem driver must configure all the covered offsets as protected
10744 /// before responding to this message with success.
10745 ///
10746 /// On failure, the securemem driver must ensure the protected range was not
10747 /// created.
10748 ///
10749 /// Sysmem must only call this up to once if dynamic_protection_ranges
10750 /// false.
10751 ///
10752 /// If dynamic_protection_ranges is true, sysmem can call this multiple
10753 /// times as long as the current number of ranges never exceeds
10754 /// max_protected_range_count.
10755 ///
10756 /// The caller must not attempt to add a range that matches an
10757 /// already-existing range. Added ranges can overlap each other as long as
10758 /// no two ranges match exactly.
10759 ///
10760 /// Errors:
10761 /// * ZX_ERR_BAD_STATE - called more than once when
10762 /// !dynamic_protection_ranges. Adding a heap that would cause overall
10763 /// heap count to exceed max_protected_range_count.
10764 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10765 /// to protected_range_granularity.
10766 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10767 /// with TEE which doesn't generate zx_status_t errors).
10768 /// * other errors are possible, such as from communication failures or
10769 /// server propagation of zx_status_t failures.
10770 pub fn r#add_secure_heap_physical_range(
10771 &self,
10772 mut heap_range: &SecureHeapAndRange,
10773 ) -> fidl::client::QueryResponseFut<
10774 SecureMemAddSecureHeapPhysicalRangeResult,
10775 fidl::encoding::DefaultFuchsiaResourceDialect,
10776 > {
10777 SecureMemProxyInterface::r#add_secure_heap_physical_range(self, heap_range)
10778 }
10779
10780 /// This request from sysmem to the securemem driver conveys a physical
10781 /// range to delete, for a heap whose physical range(s) are set up via
10782 /// sysmem.
10783 ///
10784 /// Only sysmem can call this because only sysmem is handed the client end
10785 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10786 /// securemem driver is the server end of this protocol.
10787 ///
10788 /// The securemem driver must configure all the covered offsets as not
10789 /// protected before responding to this message with success.
10790 ///
10791 /// On failure, the securemem driver must ensure the protected range was not
10792 /// deleted.
10793 ///
10794 /// Sysmem must not call this if dynamic_protection_ranges false.
10795 ///
10796 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10797 /// on various ranges that exist at the time of the call.
10798 ///
10799 /// If any portion of the range being deleted is not also covered by another
10800 /// protected range, then any ongoing DMA to any part of the entire range
10801 /// may be interrupted / may fail, potentially in a way that's disruptive to
10802 /// the entire system (bus lockup or similar, depending on device details).
10803 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
10804 /// any portion of the range being deleted, unless the caller has other
10805 /// active ranges covering every block of the range being deleted. Ongoing
10806 /// DMA to/from blocks outside the range being deleted is never impacted by
10807 /// the deletion.
10808 ///
10809 /// Errors:
10810 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10811 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10812 /// to protected_range_granularity.
10813 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10814 /// with TEE which doesn't generate zx_status_t errors).
10815 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10816 /// * other errors are possible, such as from communication failures or
10817 /// server propagation of zx_status_t failures.
10818 pub fn r#delete_secure_heap_physical_range(
10819 &self,
10820 mut heap_range: &SecureHeapAndRange,
10821 ) -> fidl::client::QueryResponseFut<
10822 SecureMemDeleteSecureHeapPhysicalRangeResult,
10823 fidl::encoding::DefaultFuchsiaResourceDialect,
10824 > {
10825 SecureMemProxyInterface::r#delete_secure_heap_physical_range(self, heap_range)
10826 }
10827
10828 /// This request from sysmem to the securemem driver conveys a physical
10829 /// range to modify and its new base and length, for a heap whose physical
10830 /// range(s) are set up via sysmem.
10831 ///
10832 /// Only sysmem can call this because only sysmem is handed the client end
10833 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10834 /// securemem driver is the server end of this protocol.
10835 ///
10836 /// The securemem driver must configure the range to cover only the new
10837 /// offsets before responding to this message with success.
10838 ///
10839 /// On failure, the securemem driver must ensure the range was not changed.
10840 ///
10841 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
10842 /// must not call this if !is_mod_protected_range_available.
10843 ///
10844 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10845 /// on various ranges that exist at the time of the call.
10846 ///
10847 /// The range must only be modified at one end or the other, but not both.
10848 /// If the range is getting shorter, and the un-covered blocks are not
10849 /// covered by other active ranges, any ongoing DMA to the entire range
10850 /// that's geting shorter may fail in a way that disrupts the entire system
10851 /// (bus lockup or similar), so the caller must ensure that no DMA is
10852 /// ongoing to any portion of a range that is getting shorter, unless the
10853 /// blocks being un-covered by the modification to this range are all
10854 /// covered by other active ranges, in which case no disruption to ongoing
10855 /// DMA will occur.
10856 ///
10857 /// If a range is modified to become <= zero length, the range is deleted.
10858 ///
10859 /// Errors:
10860 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10861 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
10862 /// that doesn't conform to protected_range_granularity, or old_range
10863 /// and new_range differ in both begin and end (disallowed).
10864 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10865 /// with TEE which doesn't generate zx_status_t errors).
10866 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10867 /// * other errors are possible, such as from communication failures or
10868 /// server propagation of zx_status_t failures.
10869 pub fn r#modify_secure_heap_physical_range(
10870 &self,
10871 mut range_modification: &SecureHeapAndRangeModification,
10872 ) -> fidl::client::QueryResponseFut<
10873 SecureMemModifySecureHeapPhysicalRangeResult,
10874 fidl::encoding::DefaultFuchsiaResourceDialect,
10875 > {
10876 SecureMemProxyInterface::r#modify_secure_heap_physical_range(self, range_modification)
10877 }
10878
10879 /// Zero a sub-range of a currently-existing physical range added via
10880 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
10881 /// exactly one physical range, and must not overlap with any other
10882 /// physical range.
10883 ///
10884 /// is_covering_range_explicit - When true, the covering range must be one
10885 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
10886 /// possibly modified since. When false, the covering range must not
10887 /// be one of the ranges explicitly created via
10888 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
10889 /// a covering range not created via AddSecureHeapPhysicalRange(). The
10890 /// covering range is typically the entire physical range (or a range
10891 /// which covers even more) of a heap configured by the TEE and whose
10892 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
10893 ///
10894 /// Ongoing DMA is not disrupted by this request.
10895 pub fn r#zero_sub_range(
10896 &self,
10897 mut is_covering_range_explicit: bool,
10898 mut heap_range: &SecureHeapAndRange,
10899 ) -> fidl::client::QueryResponseFut<
10900 SecureMemZeroSubRangeResult,
10901 fidl::encoding::DefaultFuchsiaResourceDialect,
10902 > {
10903 SecureMemProxyInterface::r#zero_sub_range(self, is_covering_range_explicit, heap_range)
10904 }
10905}
10906
10907impl SecureMemProxyInterface for SecureMemProxy {
10908 type GetPhysicalSecureHeapsResponseFut = fidl::client::QueryResponseFut<
10909 SecureMemGetPhysicalSecureHeapsResult,
10910 fidl::encoding::DefaultFuchsiaResourceDialect,
10911 >;
10912 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut {
10913 fn _decode(
10914 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10915 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
10916 let _response = fidl::client::decode_transaction_body::<
10917 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapsResponse, i32>,
10918 fidl::encoding::DefaultFuchsiaResourceDialect,
10919 0x782319d6ce7fa05,
10920 >(_buf?)?;
10921 Ok(_response.map(|x| x.heaps))
10922 }
10923 self.client.send_query_and_decode::<
10924 fidl::encoding::EmptyPayload,
10925 SecureMemGetPhysicalSecureHeapsResult,
10926 >(
10927 (),
10928 0x782319d6ce7fa05,
10929 fidl::encoding::DynamicFlags::empty(),
10930 _decode,
10931 )
10932 }
10933
10934 type GetPhysicalSecureHeapPropertiesResponseFut = fidl::client::QueryResponseFut<
10935 SecureMemGetPhysicalSecureHeapPropertiesResult,
10936 fidl::encoding::DefaultFuchsiaResourceDialect,
10937 >;
10938 fn r#get_physical_secure_heap_properties(
10939 &self,
10940 mut entire_heap: &SecureHeapAndRange,
10941 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut {
10942 fn _decode(
10943 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10944 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
10945 let _response = fidl::client::decode_transaction_body::<
10946 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapPropertiesResponse, i32>,
10947 fidl::encoding::DefaultFuchsiaResourceDialect,
10948 0x26404e23f1271214,
10949 >(_buf?)?;
10950 Ok(_response.map(|x| x.properties))
10951 }
10952 self.client.send_query_and_decode::<
10953 SecureMemGetPhysicalSecureHeapPropertiesRequest,
10954 SecureMemGetPhysicalSecureHeapPropertiesResult,
10955 >(
10956 (entire_heap,),
10957 0x26404e23f1271214,
10958 fidl::encoding::DynamicFlags::empty(),
10959 _decode,
10960 )
10961 }
10962
10963 type AddSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10964 SecureMemAddSecureHeapPhysicalRangeResult,
10965 fidl::encoding::DefaultFuchsiaResourceDialect,
10966 >;
10967 fn r#add_secure_heap_physical_range(
10968 &self,
10969 mut heap_range: &SecureHeapAndRange,
10970 ) -> Self::AddSecureHeapPhysicalRangeResponseFut {
10971 fn _decode(
10972 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10973 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
10974 let _response = fidl::client::decode_transaction_body::<
10975 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10976 fidl::encoding::DefaultFuchsiaResourceDialect,
10977 0x1ca1abcee8a0b33e,
10978 >(_buf?)?;
10979 Ok(_response.map(|x| x))
10980 }
10981 self.client.send_query_and_decode::<
10982 SecureMemAddSecureHeapPhysicalRangeRequest,
10983 SecureMemAddSecureHeapPhysicalRangeResult,
10984 >(
10985 (heap_range,),
10986 0x1ca1abcee8a0b33e,
10987 fidl::encoding::DynamicFlags::empty(),
10988 _decode,
10989 )
10990 }
10991
10992 type DeleteSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10993 SecureMemDeleteSecureHeapPhysicalRangeResult,
10994 fidl::encoding::DefaultFuchsiaResourceDialect,
10995 >;
10996 fn r#delete_secure_heap_physical_range(
10997 &self,
10998 mut heap_range: &SecureHeapAndRange,
10999 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut {
11000 fn _decode(
11001 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
11002 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
11003 let _response = fidl::client::decode_transaction_body::<
11004 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
11005 fidl::encoding::DefaultFuchsiaResourceDialect,
11006 0x728a953e56df92ee,
11007 >(_buf?)?;
11008 Ok(_response.map(|x| x))
11009 }
11010 self.client.send_query_and_decode::<
11011 SecureMemDeleteSecureHeapPhysicalRangeRequest,
11012 SecureMemDeleteSecureHeapPhysicalRangeResult,
11013 >(
11014 (heap_range,),
11015 0x728a953e56df92ee,
11016 fidl::encoding::DynamicFlags::empty(),
11017 _decode,
11018 )
11019 }
11020
11021 type ModifySecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
11022 SecureMemModifySecureHeapPhysicalRangeResult,
11023 fidl::encoding::DefaultFuchsiaResourceDialect,
11024 >;
11025 fn r#modify_secure_heap_physical_range(
11026 &self,
11027 mut range_modification: &SecureHeapAndRangeModification,
11028 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut {
11029 fn _decode(
11030 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
11031 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
11032 let _response = fidl::client::decode_transaction_body::<
11033 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
11034 fidl::encoding::DefaultFuchsiaResourceDialect,
11035 0x154fbfa3646a890d,
11036 >(_buf?)?;
11037 Ok(_response.map(|x| x))
11038 }
11039 self.client.send_query_and_decode::<
11040 SecureMemModifySecureHeapPhysicalRangeRequest,
11041 SecureMemModifySecureHeapPhysicalRangeResult,
11042 >(
11043 (range_modification,),
11044 0x154fbfa3646a890d,
11045 fidl::encoding::DynamicFlags::empty(),
11046 _decode,
11047 )
11048 }
11049
11050 type ZeroSubRangeResponseFut = fidl::client::QueryResponseFut<
11051 SecureMemZeroSubRangeResult,
11052 fidl::encoding::DefaultFuchsiaResourceDialect,
11053 >;
11054 fn r#zero_sub_range(
11055 &self,
11056 mut is_covering_range_explicit: bool,
11057 mut heap_range: &SecureHeapAndRange,
11058 ) -> Self::ZeroSubRangeResponseFut {
11059 fn _decode(
11060 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
11061 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
11062 let _response = fidl::client::decode_transaction_body::<
11063 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
11064 fidl::encoding::DefaultFuchsiaResourceDialect,
11065 0x7480f72bb5bc7e5b,
11066 >(_buf?)?;
11067 Ok(_response.map(|x| x))
11068 }
11069 self.client
11070 .send_query_and_decode::<SecureMemZeroSubRangeRequest, SecureMemZeroSubRangeResult>(
11071 (is_covering_range_explicit, heap_range),
11072 0x7480f72bb5bc7e5b,
11073 fidl::encoding::DynamicFlags::empty(),
11074 _decode,
11075 )
11076 }
11077}
11078
11079pub struct SecureMemEventStream {
11080 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
11081}
11082
11083impl std::marker::Unpin for SecureMemEventStream {}
11084
11085impl futures::stream::FusedStream for SecureMemEventStream {
11086 fn is_terminated(&self) -> bool {
11087 self.event_receiver.is_terminated()
11088 }
11089}
11090
11091impl futures::Stream for SecureMemEventStream {
11092 type Item = Result<SecureMemEvent, fidl::Error>;
11093
11094 fn poll_next(
11095 mut self: std::pin::Pin<&mut Self>,
11096 cx: &mut std::task::Context<'_>,
11097 ) -> std::task::Poll<Option<Self::Item>> {
11098 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
11099 &mut self.event_receiver,
11100 cx
11101 )?) {
11102 Some(buf) => std::task::Poll::Ready(Some(SecureMemEvent::decode(buf))),
11103 None => std::task::Poll::Ready(None),
11104 }
11105 }
11106}
11107
11108#[derive(Debug)]
11109pub enum SecureMemEvent {}
11110
11111impl SecureMemEvent {
11112 /// Decodes a message buffer as a [`SecureMemEvent`].
11113 fn decode(
11114 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
11115 ) -> Result<SecureMemEvent, fidl::Error> {
11116 let (bytes, _handles) = buf.split_mut();
11117 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
11118 debug_assert_eq!(tx_header.tx_id, 0);
11119 match tx_header.ordinal {
11120 _ => Err(fidl::Error::UnknownOrdinal {
11121 ordinal: tx_header.ordinal,
11122 protocol_name: <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
11123 }),
11124 }
11125 }
11126}
11127
11128/// A Stream of incoming requests for fuchsia.sysmem/SecureMem.
11129pub struct SecureMemRequestStream {
11130 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11131 is_terminated: bool,
11132}
11133
11134impl std::marker::Unpin for SecureMemRequestStream {}
11135
11136impl futures::stream::FusedStream for SecureMemRequestStream {
11137 fn is_terminated(&self) -> bool {
11138 self.is_terminated
11139 }
11140}
11141
11142impl fidl::endpoints::RequestStream for SecureMemRequestStream {
11143 type Protocol = SecureMemMarker;
11144 type ControlHandle = SecureMemControlHandle;
11145
11146 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
11147 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
11148 }
11149
11150 fn control_handle(&self) -> Self::ControlHandle {
11151 SecureMemControlHandle { inner: self.inner.clone() }
11152 }
11153
11154 fn into_inner(
11155 self,
11156 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
11157 {
11158 (self.inner, self.is_terminated)
11159 }
11160
11161 fn from_inner(
11162 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11163 is_terminated: bool,
11164 ) -> Self {
11165 Self { inner, is_terminated }
11166 }
11167}
11168
11169impl futures::Stream for SecureMemRequestStream {
11170 type Item = Result<SecureMemRequest, fidl::Error>;
11171
11172 fn poll_next(
11173 mut self: std::pin::Pin<&mut Self>,
11174 cx: &mut std::task::Context<'_>,
11175 ) -> std::task::Poll<Option<Self::Item>> {
11176 let this = &mut *self;
11177 if this.inner.check_shutdown(cx) {
11178 this.is_terminated = true;
11179 return std::task::Poll::Ready(None);
11180 }
11181 if this.is_terminated {
11182 panic!("polled SecureMemRequestStream after completion");
11183 }
11184 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
11185 |bytes, handles| {
11186 match this.inner.channel().read_etc(cx, bytes, handles) {
11187 std::task::Poll::Ready(Ok(())) => {}
11188 std::task::Poll::Pending => return std::task::Poll::Pending,
11189 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
11190 this.is_terminated = true;
11191 return std::task::Poll::Ready(None);
11192 }
11193 std::task::Poll::Ready(Err(e)) => {
11194 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
11195 e.into(),
11196 ))))
11197 }
11198 }
11199
11200 // A message has been received from the channel
11201 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
11202
11203 std::task::Poll::Ready(Some(match header.ordinal {
11204 0x782319d6ce7fa05 => {
11205 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11206 let mut req = fidl::new_empty!(
11207 fidl::encoding::EmptyPayload,
11208 fidl::encoding::DefaultFuchsiaResourceDialect
11209 );
11210 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11211 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11212 Ok(SecureMemRequest::GetPhysicalSecureHeaps {
11213 responder: SecureMemGetPhysicalSecureHeapsResponder {
11214 control_handle: std::mem::ManuallyDrop::new(control_handle),
11215 tx_id: header.tx_id,
11216 },
11217 })
11218 }
11219 0x26404e23f1271214 => {
11220 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11221 let mut req = fidl::new_empty!(
11222 SecureMemGetPhysicalSecureHeapPropertiesRequest,
11223 fidl::encoding::DefaultFuchsiaResourceDialect
11224 );
11225 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemGetPhysicalSecureHeapPropertiesRequest>(&header, _body_bytes, handles, &mut req)?;
11226 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11227 Ok(SecureMemRequest::GetPhysicalSecureHeapProperties {
11228 entire_heap: req.entire_heap,
11229
11230 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder {
11231 control_handle: std::mem::ManuallyDrop::new(control_handle),
11232 tx_id: header.tx_id,
11233 },
11234 })
11235 }
11236 0x1ca1abcee8a0b33e => {
11237 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11238 let mut req = fidl::new_empty!(
11239 SecureMemAddSecureHeapPhysicalRangeRequest,
11240 fidl::encoding::DefaultFuchsiaResourceDialect
11241 );
11242 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemAddSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11243 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11244 Ok(SecureMemRequest::AddSecureHeapPhysicalRange {
11245 heap_range: req.heap_range,
11246
11247 responder: SecureMemAddSecureHeapPhysicalRangeResponder {
11248 control_handle: std::mem::ManuallyDrop::new(control_handle),
11249 tx_id: header.tx_id,
11250 },
11251 })
11252 }
11253 0x728a953e56df92ee => {
11254 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11255 let mut req = fidl::new_empty!(
11256 SecureMemDeleteSecureHeapPhysicalRangeRequest,
11257 fidl::encoding::DefaultFuchsiaResourceDialect
11258 );
11259 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemDeleteSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11260 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11261 Ok(SecureMemRequest::DeleteSecureHeapPhysicalRange {
11262 heap_range: req.heap_range,
11263
11264 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder {
11265 control_handle: std::mem::ManuallyDrop::new(control_handle),
11266 tx_id: header.tx_id,
11267 },
11268 })
11269 }
11270 0x154fbfa3646a890d => {
11271 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11272 let mut req = fidl::new_empty!(
11273 SecureMemModifySecureHeapPhysicalRangeRequest,
11274 fidl::encoding::DefaultFuchsiaResourceDialect
11275 );
11276 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemModifySecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11277 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11278 Ok(SecureMemRequest::ModifySecureHeapPhysicalRange {
11279 range_modification: req.range_modification,
11280
11281 responder: SecureMemModifySecureHeapPhysicalRangeResponder {
11282 control_handle: std::mem::ManuallyDrop::new(control_handle),
11283 tx_id: header.tx_id,
11284 },
11285 })
11286 }
11287 0x7480f72bb5bc7e5b => {
11288 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11289 let mut req = fidl::new_empty!(
11290 SecureMemZeroSubRangeRequest,
11291 fidl::encoding::DefaultFuchsiaResourceDialect
11292 );
11293 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemZeroSubRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11294 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11295 Ok(SecureMemRequest::ZeroSubRange {
11296 is_covering_range_explicit: req.is_covering_range_explicit,
11297 heap_range: req.heap_range,
11298
11299 responder: SecureMemZeroSubRangeResponder {
11300 control_handle: std::mem::ManuallyDrop::new(control_handle),
11301 tx_id: header.tx_id,
11302 },
11303 })
11304 }
11305 _ => Err(fidl::Error::UnknownOrdinal {
11306 ordinal: header.ordinal,
11307 protocol_name:
11308 <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
11309 }),
11310 }))
11311 },
11312 )
11313 }
11314}
11315
11316/// SecureMem
11317///
11318/// The client is sysmem. The server is securemem driver.
11319///
11320/// TEE - Trusted Execution Environment.
11321///
11322/// REE - Rich Execution Environment.
11323///
11324/// Enables sysmem to call the securemem driver to get any secure heaps
11325/// configured via the TEE (or via the securemem driver), and set any physical
11326/// secure heaps configured via sysmem.
11327///
11328/// Presently, dynamically-allocated secure heaps are configured via sysmem, as
11329/// it starts quite early during boot and can successfully reserve contiguous
11330/// physical memory. Presently, fixed-location secure heaps are configured via
11331/// TEE, as the plumbing goes from the bootloader to the TEE. However, this
11332/// protocol intentionally doesn't care which heaps are dynamically-allocated
11333/// and which are fixed-location.
11334#[derive(Debug)]
11335pub enum SecureMemRequest {
11336 /// Gets the physical address and length of any secure heap whose physical
11337 /// range is configured via the TEE.
11338 ///
11339 /// Presently, these will be fixed physical addresses and lengths, with the
11340 /// location plumbed via the TEE.
11341 ///
11342 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
11343 /// when there isn't any special heap-specific per-VMO setup or teardown
11344 /// required.
11345 ///
11346 /// The physical range must be secured/protected by the TEE before the
11347 /// securemem driver responds to this request with success.
11348 ///
11349 /// Sysmem should only call this once. Returning zero heaps is not a
11350 /// failure.
11351 ///
11352 /// Errors:
11353 /// * ZX_ERR_BAD_STATE - called more than once.
11354 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11355 /// with TEE which doesn't generate zx_status_t errors).
11356 /// * other errors are allowed; any other errors should be treated the same
11357 /// as ZX_ERR_INTERNAL.
11358 GetPhysicalSecureHeaps { responder: SecureMemGetPhysicalSecureHeapsResponder },
11359 /// This request from sysmem to the securemem driver gets the properties of
11360 /// a protected/secure heap.
11361 ///
11362 /// This only handles heaps with a single contiguous physical extent.
11363 ///
11364 /// The heap's entire physical range is indicated in case this request needs
11365 /// some physical space to auto-detect how many ranges are REE-usable. Any
11366 /// temporary HW protection ranges will be deleted before this request
11367 /// completes.
11368 GetPhysicalSecureHeapProperties {
11369 entire_heap: SecureHeapAndRange,
11370 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder,
11371 },
11372 /// This request from sysmem to the securemem driver conveys a physical
11373 /// range to add, for a heap whose physical range(s) are set up via
11374 /// sysmem.
11375 ///
11376 /// Only sysmem can call this because only sysmem is handed the client end
11377 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11378 /// securemem driver is the server end of this protocol.
11379 ///
11380 /// The securemem driver must configure all the covered offsets as protected
11381 /// before responding to this message with success.
11382 ///
11383 /// On failure, the securemem driver must ensure the protected range was not
11384 /// created.
11385 ///
11386 /// Sysmem must only call this up to once if dynamic_protection_ranges
11387 /// false.
11388 ///
11389 /// If dynamic_protection_ranges is true, sysmem can call this multiple
11390 /// times as long as the current number of ranges never exceeds
11391 /// max_protected_range_count.
11392 ///
11393 /// The caller must not attempt to add a range that matches an
11394 /// already-existing range. Added ranges can overlap each other as long as
11395 /// no two ranges match exactly.
11396 ///
11397 /// Errors:
11398 /// * ZX_ERR_BAD_STATE - called more than once when
11399 /// !dynamic_protection_ranges. Adding a heap that would cause overall
11400 /// heap count to exceed max_protected_range_count.
11401 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
11402 /// to protected_range_granularity.
11403 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11404 /// with TEE which doesn't generate zx_status_t errors).
11405 /// * other errors are possible, such as from communication failures or
11406 /// server propagation of zx_status_t failures.
11407 AddSecureHeapPhysicalRange {
11408 heap_range: SecureHeapAndRange,
11409 responder: SecureMemAddSecureHeapPhysicalRangeResponder,
11410 },
11411 /// This request from sysmem to the securemem driver conveys a physical
11412 /// range to delete, for a heap whose physical range(s) are set up via
11413 /// sysmem.
11414 ///
11415 /// Only sysmem can call this because only sysmem is handed the client end
11416 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11417 /// securemem driver is the server end of this protocol.
11418 ///
11419 /// The securemem driver must configure all the covered offsets as not
11420 /// protected before responding to this message with success.
11421 ///
11422 /// On failure, the securemem driver must ensure the protected range was not
11423 /// deleted.
11424 ///
11425 /// Sysmem must not call this if dynamic_protection_ranges false.
11426 ///
11427 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
11428 /// on various ranges that exist at the time of the call.
11429 ///
11430 /// If any portion of the range being deleted is not also covered by another
11431 /// protected range, then any ongoing DMA to any part of the entire range
11432 /// may be interrupted / may fail, potentially in a way that's disruptive to
11433 /// the entire system (bus lockup or similar, depending on device details).
11434 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
11435 /// any portion of the range being deleted, unless the caller has other
11436 /// active ranges covering every block of the range being deleted. Ongoing
11437 /// DMA to/from blocks outside the range being deleted is never impacted by
11438 /// the deletion.
11439 ///
11440 /// Errors:
11441 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
11442 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
11443 /// to protected_range_granularity.
11444 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11445 /// with TEE which doesn't generate zx_status_t errors).
11446 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
11447 /// * other errors are possible, such as from communication failures or
11448 /// server propagation of zx_status_t failures.
11449 DeleteSecureHeapPhysicalRange {
11450 heap_range: SecureHeapAndRange,
11451 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder,
11452 },
11453 /// This request from sysmem to the securemem driver conveys a physical
11454 /// range to modify and its new base and length, for a heap whose physical
11455 /// range(s) are set up via sysmem.
11456 ///
11457 /// Only sysmem can call this because only sysmem is handed the client end
11458 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11459 /// securemem driver is the server end of this protocol.
11460 ///
11461 /// The securemem driver must configure the range to cover only the new
11462 /// offsets before responding to this message with success.
11463 ///
11464 /// On failure, the securemem driver must ensure the range was not changed.
11465 ///
11466 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
11467 /// must not call this if !is_mod_protected_range_available.
11468 ///
11469 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
11470 /// on various ranges that exist at the time of the call.
11471 ///
11472 /// The range must only be modified at one end or the other, but not both.
11473 /// If the range is getting shorter, and the un-covered blocks are not
11474 /// covered by other active ranges, any ongoing DMA to the entire range
11475 /// that's geting shorter may fail in a way that disrupts the entire system
11476 /// (bus lockup or similar), so the caller must ensure that no DMA is
11477 /// ongoing to any portion of a range that is getting shorter, unless the
11478 /// blocks being un-covered by the modification to this range are all
11479 /// covered by other active ranges, in which case no disruption to ongoing
11480 /// DMA will occur.
11481 ///
11482 /// If a range is modified to become <= zero length, the range is deleted.
11483 ///
11484 /// Errors:
11485 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
11486 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
11487 /// that doesn't conform to protected_range_granularity, or old_range
11488 /// and new_range differ in both begin and end (disallowed).
11489 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11490 /// with TEE which doesn't generate zx_status_t errors).
11491 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
11492 /// * other errors are possible, such as from communication failures or
11493 /// server propagation of zx_status_t failures.
11494 ModifySecureHeapPhysicalRange {
11495 range_modification: SecureHeapAndRangeModification,
11496 responder: SecureMemModifySecureHeapPhysicalRangeResponder,
11497 },
11498 /// Zero a sub-range of a currently-existing physical range added via
11499 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
11500 /// exactly one physical range, and must not overlap with any other
11501 /// physical range.
11502 ///
11503 /// is_covering_range_explicit - When true, the covering range must be one
11504 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
11505 /// possibly modified since. When false, the covering range must not
11506 /// be one of the ranges explicitly created via
11507 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
11508 /// a covering range not created via AddSecureHeapPhysicalRange(). The
11509 /// covering range is typically the entire physical range (or a range
11510 /// which covers even more) of a heap configured by the TEE and whose
11511 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
11512 ///
11513 /// Ongoing DMA is not disrupted by this request.
11514 ZeroSubRange {
11515 is_covering_range_explicit: bool,
11516 heap_range: SecureHeapAndRange,
11517 responder: SecureMemZeroSubRangeResponder,
11518 },
11519}
11520
11521impl SecureMemRequest {
11522 #[allow(irrefutable_let_patterns)]
11523 pub fn into_get_physical_secure_heaps(
11524 self,
11525 ) -> Option<(SecureMemGetPhysicalSecureHeapsResponder)> {
11526 if let SecureMemRequest::GetPhysicalSecureHeaps { responder } = self {
11527 Some((responder))
11528 } else {
11529 None
11530 }
11531 }
11532
11533 #[allow(irrefutable_let_patterns)]
11534 pub fn into_get_physical_secure_heap_properties(
11535 self,
11536 ) -> Option<(SecureHeapAndRange, SecureMemGetPhysicalSecureHeapPropertiesResponder)> {
11537 if let SecureMemRequest::GetPhysicalSecureHeapProperties { entire_heap, responder } = self {
11538 Some((entire_heap, responder))
11539 } else {
11540 None
11541 }
11542 }
11543
11544 #[allow(irrefutable_let_patterns)]
11545 pub fn into_add_secure_heap_physical_range(
11546 self,
11547 ) -> Option<(SecureHeapAndRange, SecureMemAddSecureHeapPhysicalRangeResponder)> {
11548 if let SecureMemRequest::AddSecureHeapPhysicalRange { heap_range, responder } = self {
11549 Some((heap_range, responder))
11550 } else {
11551 None
11552 }
11553 }
11554
11555 #[allow(irrefutable_let_patterns)]
11556 pub fn into_delete_secure_heap_physical_range(
11557 self,
11558 ) -> Option<(SecureHeapAndRange, SecureMemDeleteSecureHeapPhysicalRangeResponder)> {
11559 if let SecureMemRequest::DeleteSecureHeapPhysicalRange { heap_range, responder } = self {
11560 Some((heap_range, responder))
11561 } else {
11562 None
11563 }
11564 }
11565
11566 #[allow(irrefutable_let_patterns)]
11567 pub fn into_modify_secure_heap_physical_range(
11568 self,
11569 ) -> Option<(SecureHeapAndRangeModification, SecureMemModifySecureHeapPhysicalRangeResponder)>
11570 {
11571 if let SecureMemRequest::ModifySecureHeapPhysicalRange { range_modification, responder } =
11572 self
11573 {
11574 Some((range_modification, responder))
11575 } else {
11576 None
11577 }
11578 }
11579
11580 #[allow(irrefutable_let_patterns)]
11581 pub fn into_zero_sub_range(
11582 self,
11583 ) -> Option<(bool, SecureHeapAndRange, SecureMemZeroSubRangeResponder)> {
11584 if let SecureMemRequest::ZeroSubRange {
11585 is_covering_range_explicit,
11586 heap_range,
11587 responder,
11588 } = self
11589 {
11590 Some((is_covering_range_explicit, heap_range, responder))
11591 } else {
11592 None
11593 }
11594 }
11595
11596 /// Name of the method defined in FIDL
11597 pub fn method_name(&self) -> &'static str {
11598 match *self {
11599 SecureMemRequest::GetPhysicalSecureHeaps { .. } => "get_physical_secure_heaps",
11600 SecureMemRequest::GetPhysicalSecureHeapProperties { .. } => {
11601 "get_physical_secure_heap_properties"
11602 }
11603 SecureMemRequest::AddSecureHeapPhysicalRange { .. } => "add_secure_heap_physical_range",
11604 SecureMemRequest::DeleteSecureHeapPhysicalRange { .. } => {
11605 "delete_secure_heap_physical_range"
11606 }
11607 SecureMemRequest::ModifySecureHeapPhysicalRange { .. } => {
11608 "modify_secure_heap_physical_range"
11609 }
11610 SecureMemRequest::ZeroSubRange { .. } => "zero_sub_range",
11611 }
11612 }
11613}
11614
11615#[derive(Debug, Clone)]
11616pub struct SecureMemControlHandle {
11617 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11618}
11619
11620impl fidl::endpoints::ControlHandle for SecureMemControlHandle {
11621 fn shutdown(&self) {
11622 self.inner.shutdown()
11623 }
11624 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
11625 self.inner.shutdown_with_epitaph(status)
11626 }
11627
11628 fn is_closed(&self) -> bool {
11629 self.inner.channel().is_closed()
11630 }
11631 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
11632 self.inner.channel().on_closed()
11633 }
11634
11635 #[cfg(target_os = "fuchsia")]
11636 fn signal_peer(
11637 &self,
11638 clear_mask: zx::Signals,
11639 set_mask: zx::Signals,
11640 ) -> Result<(), zx_status::Status> {
11641 use fidl::Peered;
11642 self.inner.channel().signal_peer(clear_mask, set_mask)
11643 }
11644}
11645
11646impl SecureMemControlHandle {}
11647
11648#[must_use = "FIDL methods require a response to be sent"]
11649#[derive(Debug)]
11650pub struct SecureMemGetPhysicalSecureHeapsResponder {
11651 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11652 tx_id: u32,
11653}
11654
11655/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11656/// if the responder is dropped without sending a response, so that the client
11657/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11658impl std::ops::Drop for SecureMemGetPhysicalSecureHeapsResponder {
11659 fn drop(&mut self) {
11660 self.control_handle.shutdown();
11661 // Safety: drops once, never accessed again
11662 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11663 }
11664}
11665
11666impl fidl::endpoints::Responder for SecureMemGetPhysicalSecureHeapsResponder {
11667 type ControlHandle = SecureMemControlHandle;
11668
11669 fn control_handle(&self) -> &SecureMemControlHandle {
11670 &self.control_handle
11671 }
11672
11673 fn drop_without_shutdown(mut self) {
11674 // Safety: drops once, never accessed again due to mem::forget
11675 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11676 // Prevent Drop from running (which would shut down the channel)
11677 std::mem::forget(self);
11678 }
11679}
11680
11681impl SecureMemGetPhysicalSecureHeapsResponder {
11682 /// Sends a response to the FIDL transaction.
11683 ///
11684 /// Sets the channel to shutdown if an error occurs.
11685 pub fn send(self, mut result: Result<&SecureHeapsAndRanges, i32>) -> Result<(), fidl::Error> {
11686 let _result = self.send_raw(result);
11687 if _result.is_err() {
11688 self.control_handle.shutdown();
11689 }
11690 self.drop_without_shutdown();
11691 _result
11692 }
11693
11694 /// Similar to "send" but does not shutdown the channel if an error occurs.
11695 pub fn send_no_shutdown_on_err(
11696 self,
11697 mut result: Result<&SecureHeapsAndRanges, i32>,
11698 ) -> Result<(), fidl::Error> {
11699 let _result = self.send_raw(result);
11700 self.drop_without_shutdown();
11701 _result
11702 }
11703
11704 fn send_raw(&self, mut result: Result<&SecureHeapsAndRanges, i32>) -> Result<(), fidl::Error> {
11705 self.control_handle.inner.send::<fidl::encoding::ResultType<
11706 SecureMemGetPhysicalSecureHeapsResponse,
11707 i32,
11708 >>(
11709 result.map(|heaps| (heaps,)),
11710 self.tx_id,
11711 0x782319d6ce7fa05,
11712 fidl::encoding::DynamicFlags::empty(),
11713 )
11714 }
11715}
11716
11717#[must_use = "FIDL methods require a response to be sent"]
11718#[derive(Debug)]
11719pub struct SecureMemGetPhysicalSecureHeapPropertiesResponder {
11720 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11721 tx_id: u32,
11722}
11723
11724/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11725/// if the responder is dropped without sending a response, so that the client
11726/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11727impl std::ops::Drop for SecureMemGetPhysicalSecureHeapPropertiesResponder {
11728 fn drop(&mut self) {
11729 self.control_handle.shutdown();
11730 // Safety: drops once, never accessed again
11731 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11732 }
11733}
11734
11735impl fidl::endpoints::Responder for SecureMemGetPhysicalSecureHeapPropertiesResponder {
11736 type ControlHandle = SecureMemControlHandle;
11737
11738 fn control_handle(&self) -> &SecureMemControlHandle {
11739 &self.control_handle
11740 }
11741
11742 fn drop_without_shutdown(mut self) {
11743 // Safety: drops once, never accessed again due to mem::forget
11744 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11745 // Prevent Drop from running (which would shut down the channel)
11746 std::mem::forget(self);
11747 }
11748}
11749
11750impl SecureMemGetPhysicalSecureHeapPropertiesResponder {
11751 /// Sends a response to the FIDL transaction.
11752 ///
11753 /// Sets the channel to shutdown if an error occurs.
11754 pub fn send(self, mut result: Result<&SecureHeapProperties, i32>) -> Result<(), fidl::Error> {
11755 let _result = self.send_raw(result);
11756 if _result.is_err() {
11757 self.control_handle.shutdown();
11758 }
11759 self.drop_without_shutdown();
11760 _result
11761 }
11762
11763 /// Similar to "send" but does not shutdown the channel if an error occurs.
11764 pub fn send_no_shutdown_on_err(
11765 self,
11766 mut result: Result<&SecureHeapProperties, i32>,
11767 ) -> Result<(), fidl::Error> {
11768 let _result = self.send_raw(result);
11769 self.drop_without_shutdown();
11770 _result
11771 }
11772
11773 fn send_raw(&self, mut result: Result<&SecureHeapProperties, i32>) -> Result<(), fidl::Error> {
11774 self.control_handle.inner.send::<fidl::encoding::ResultType<
11775 SecureMemGetPhysicalSecureHeapPropertiesResponse,
11776 i32,
11777 >>(
11778 result.map(|properties| (properties,)),
11779 self.tx_id,
11780 0x26404e23f1271214,
11781 fidl::encoding::DynamicFlags::empty(),
11782 )
11783 }
11784}
11785
11786#[must_use = "FIDL methods require a response to be sent"]
11787#[derive(Debug)]
11788pub struct SecureMemAddSecureHeapPhysicalRangeResponder {
11789 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11790 tx_id: u32,
11791}
11792
11793/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11794/// if the responder is dropped without sending a response, so that the client
11795/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11796impl std::ops::Drop for SecureMemAddSecureHeapPhysicalRangeResponder {
11797 fn drop(&mut self) {
11798 self.control_handle.shutdown();
11799 // Safety: drops once, never accessed again
11800 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11801 }
11802}
11803
11804impl fidl::endpoints::Responder for SecureMemAddSecureHeapPhysicalRangeResponder {
11805 type ControlHandle = SecureMemControlHandle;
11806
11807 fn control_handle(&self) -> &SecureMemControlHandle {
11808 &self.control_handle
11809 }
11810
11811 fn drop_without_shutdown(mut self) {
11812 // Safety: drops once, never accessed again due to mem::forget
11813 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11814 // Prevent Drop from running (which would shut down the channel)
11815 std::mem::forget(self);
11816 }
11817}
11818
11819impl SecureMemAddSecureHeapPhysicalRangeResponder {
11820 /// Sends a response to the FIDL transaction.
11821 ///
11822 /// Sets the channel to shutdown if an error occurs.
11823 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11824 let _result = self.send_raw(result);
11825 if _result.is_err() {
11826 self.control_handle.shutdown();
11827 }
11828 self.drop_without_shutdown();
11829 _result
11830 }
11831
11832 /// Similar to "send" but does not shutdown the channel if an error occurs.
11833 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11834 let _result = self.send_raw(result);
11835 self.drop_without_shutdown();
11836 _result
11837 }
11838
11839 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11840 self.control_handle
11841 .inner
11842 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11843 result,
11844 self.tx_id,
11845 0x1ca1abcee8a0b33e,
11846 fidl::encoding::DynamicFlags::empty(),
11847 )
11848 }
11849}
11850
11851#[must_use = "FIDL methods require a response to be sent"]
11852#[derive(Debug)]
11853pub struct SecureMemDeleteSecureHeapPhysicalRangeResponder {
11854 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11855 tx_id: u32,
11856}
11857
11858/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11859/// if the responder is dropped without sending a response, so that the client
11860/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11861impl std::ops::Drop for SecureMemDeleteSecureHeapPhysicalRangeResponder {
11862 fn drop(&mut self) {
11863 self.control_handle.shutdown();
11864 // Safety: drops once, never accessed again
11865 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11866 }
11867}
11868
11869impl fidl::endpoints::Responder for SecureMemDeleteSecureHeapPhysicalRangeResponder {
11870 type ControlHandle = SecureMemControlHandle;
11871
11872 fn control_handle(&self) -> &SecureMemControlHandle {
11873 &self.control_handle
11874 }
11875
11876 fn drop_without_shutdown(mut self) {
11877 // Safety: drops once, never accessed again due to mem::forget
11878 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11879 // Prevent Drop from running (which would shut down the channel)
11880 std::mem::forget(self);
11881 }
11882}
11883
11884impl SecureMemDeleteSecureHeapPhysicalRangeResponder {
11885 /// Sends a response to the FIDL transaction.
11886 ///
11887 /// Sets the channel to shutdown if an error occurs.
11888 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11889 let _result = self.send_raw(result);
11890 if _result.is_err() {
11891 self.control_handle.shutdown();
11892 }
11893 self.drop_without_shutdown();
11894 _result
11895 }
11896
11897 /// Similar to "send" but does not shutdown the channel if an error occurs.
11898 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11899 let _result = self.send_raw(result);
11900 self.drop_without_shutdown();
11901 _result
11902 }
11903
11904 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11905 self.control_handle
11906 .inner
11907 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11908 result,
11909 self.tx_id,
11910 0x728a953e56df92ee,
11911 fidl::encoding::DynamicFlags::empty(),
11912 )
11913 }
11914}
11915
11916#[must_use = "FIDL methods require a response to be sent"]
11917#[derive(Debug)]
11918pub struct SecureMemModifySecureHeapPhysicalRangeResponder {
11919 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11920 tx_id: u32,
11921}
11922
11923/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11924/// if the responder is dropped without sending a response, so that the client
11925/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11926impl std::ops::Drop for SecureMemModifySecureHeapPhysicalRangeResponder {
11927 fn drop(&mut self) {
11928 self.control_handle.shutdown();
11929 // Safety: drops once, never accessed again
11930 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11931 }
11932}
11933
11934impl fidl::endpoints::Responder for SecureMemModifySecureHeapPhysicalRangeResponder {
11935 type ControlHandle = SecureMemControlHandle;
11936
11937 fn control_handle(&self) -> &SecureMemControlHandle {
11938 &self.control_handle
11939 }
11940
11941 fn drop_without_shutdown(mut self) {
11942 // Safety: drops once, never accessed again due to mem::forget
11943 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11944 // Prevent Drop from running (which would shut down the channel)
11945 std::mem::forget(self);
11946 }
11947}
11948
11949impl SecureMemModifySecureHeapPhysicalRangeResponder {
11950 /// Sends a response to the FIDL transaction.
11951 ///
11952 /// Sets the channel to shutdown if an error occurs.
11953 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11954 let _result = self.send_raw(result);
11955 if _result.is_err() {
11956 self.control_handle.shutdown();
11957 }
11958 self.drop_without_shutdown();
11959 _result
11960 }
11961
11962 /// Similar to "send" but does not shutdown the channel if an error occurs.
11963 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11964 let _result = self.send_raw(result);
11965 self.drop_without_shutdown();
11966 _result
11967 }
11968
11969 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11970 self.control_handle
11971 .inner
11972 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11973 result,
11974 self.tx_id,
11975 0x154fbfa3646a890d,
11976 fidl::encoding::DynamicFlags::empty(),
11977 )
11978 }
11979}
11980
11981#[must_use = "FIDL methods require a response to be sent"]
11982#[derive(Debug)]
11983pub struct SecureMemZeroSubRangeResponder {
11984 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11985 tx_id: u32,
11986}
11987
11988/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11989/// if the responder is dropped without sending a response, so that the client
11990/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11991impl std::ops::Drop for SecureMemZeroSubRangeResponder {
11992 fn drop(&mut self) {
11993 self.control_handle.shutdown();
11994 // Safety: drops once, never accessed again
11995 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11996 }
11997}
11998
11999impl fidl::endpoints::Responder for SecureMemZeroSubRangeResponder {
12000 type ControlHandle = SecureMemControlHandle;
12001
12002 fn control_handle(&self) -> &SecureMemControlHandle {
12003 &self.control_handle
12004 }
12005
12006 fn drop_without_shutdown(mut self) {
12007 // Safety: drops once, never accessed again due to mem::forget
12008 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
12009 // Prevent Drop from running (which would shut down the channel)
12010 std::mem::forget(self);
12011 }
12012}
12013
12014impl SecureMemZeroSubRangeResponder {
12015 /// Sends a response to the FIDL transaction.
12016 ///
12017 /// Sets the channel to shutdown if an error occurs.
12018 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
12019 let _result = self.send_raw(result);
12020 if _result.is_err() {
12021 self.control_handle.shutdown();
12022 }
12023 self.drop_without_shutdown();
12024 _result
12025 }
12026
12027 /// Similar to "send" but does not shutdown the channel if an error occurs.
12028 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
12029 let _result = self.send_raw(result);
12030 self.drop_without_shutdown();
12031 _result
12032 }
12033
12034 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
12035 self.control_handle
12036 .inner
12037 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
12038 result,
12039 self.tx_id,
12040 0x7480f72bb5bc7e5b,
12041 fidl::encoding::DynamicFlags::empty(),
12042 )
12043 }
12044}
12045
12046mod internal {
12047 use super::*;
12048
12049 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateNonSharedCollectionRequest {
12050 type Borrowed<'a> = &'a mut Self;
12051 fn take_or_borrow<'a>(
12052 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12053 ) -> Self::Borrowed<'a> {
12054 value
12055 }
12056 }
12057
12058 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateNonSharedCollectionRequest {
12059 type Owned = Self;
12060
12061 #[inline(always)]
12062 fn inline_align(_context: fidl::encoding::Context) -> usize {
12063 4
12064 }
12065
12066 #[inline(always)]
12067 fn inline_size(_context: fidl::encoding::Context) -> usize {
12068 4
12069 }
12070 }
12071
12072 unsafe impl
12073 fidl::encoding::Encode<
12074 AllocatorAllocateNonSharedCollectionRequest,
12075 fidl::encoding::DefaultFuchsiaResourceDialect,
12076 > for &mut AllocatorAllocateNonSharedCollectionRequest
12077 {
12078 #[inline]
12079 unsafe fn encode(
12080 self,
12081 encoder: &mut fidl::encoding::Encoder<
12082 '_,
12083 fidl::encoding::DefaultFuchsiaResourceDialect,
12084 >,
12085 offset: usize,
12086 _depth: fidl::encoding::Depth,
12087 ) -> fidl::Result<()> {
12088 encoder.debug_check_bounds::<AllocatorAllocateNonSharedCollectionRequest>(offset);
12089 // Delegate to tuple encoding.
12090 fidl::encoding::Encode::<AllocatorAllocateNonSharedCollectionRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
12091 (
12092 <fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.collection_request),
12093 ),
12094 encoder, offset, _depth
12095 )
12096 }
12097 }
12098 unsafe impl<
12099 T0: fidl::encoding::Encode<
12100 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12101 fidl::encoding::DefaultFuchsiaResourceDialect,
12102 >,
12103 >
12104 fidl::encoding::Encode<
12105 AllocatorAllocateNonSharedCollectionRequest,
12106 fidl::encoding::DefaultFuchsiaResourceDialect,
12107 > for (T0,)
12108 {
12109 #[inline]
12110 unsafe fn encode(
12111 self,
12112 encoder: &mut fidl::encoding::Encoder<
12113 '_,
12114 fidl::encoding::DefaultFuchsiaResourceDialect,
12115 >,
12116 offset: usize,
12117 depth: fidl::encoding::Depth,
12118 ) -> fidl::Result<()> {
12119 encoder.debug_check_bounds::<AllocatorAllocateNonSharedCollectionRequest>(offset);
12120 // Zero out padding regions. There's no need to apply masks
12121 // because the unmasked parts will be overwritten by fields.
12122 // Write the fields.
12123 self.0.encode(encoder, offset + 0, depth)?;
12124 Ok(())
12125 }
12126 }
12127
12128 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12129 for AllocatorAllocateNonSharedCollectionRequest
12130 {
12131 #[inline(always)]
12132 fn new_empty() -> Self {
12133 Self {
12134 collection_request: fidl::new_empty!(
12135 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12136 fidl::encoding::DefaultFuchsiaResourceDialect
12137 ),
12138 }
12139 }
12140
12141 #[inline]
12142 unsafe fn decode(
12143 &mut self,
12144 decoder: &mut fidl::encoding::Decoder<
12145 '_,
12146 fidl::encoding::DefaultFuchsiaResourceDialect,
12147 >,
12148 offset: usize,
12149 _depth: fidl::encoding::Depth,
12150 ) -> fidl::Result<()> {
12151 decoder.debug_check_bounds::<Self>(offset);
12152 // Verify that padding bytes are zero.
12153 fidl::decode!(
12154 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12155 fidl::encoding::DefaultFuchsiaResourceDialect,
12156 &mut self.collection_request,
12157 decoder,
12158 offset + 0,
12159 _depth
12160 )?;
12161 Ok(())
12162 }
12163 }
12164
12165 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateSharedCollectionRequest {
12166 type Borrowed<'a> = &'a mut Self;
12167 fn take_or_borrow<'a>(
12168 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12169 ) -> Self::Borrowed<'a> {
12170 value
12171 }
12172 }
12173
12174 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateSharedCollectionRequest {
12175 type Owned = Self;
12176
12177 #[inline(always)]
12178 fn inline_align(_context: fidl::encoding::Context) -> usize {
12179 4
12180 }
12181
12182 #[inline(always)]
12183 fn inline_size(_context: fidl::encoding::Context) -> usize {
12184 4
12185 }
12186 }
12187
12188 unsafe impl
12189 fidl::encoding::Encode<
12190 AllocatorAllocateSharedCollectionRequest,
12191 fidl::encoding::DefaultFuchsiaResourceDialect,
12192 > for &mut AllocatorAllocateSharedCollectionRequest
12193 {
12194 #[inline]
12195 unsafe fn encode(
12196 self,
12197 encoder: &mut fidl::encoding::Encoder<
12198 '_,
12199 fidl::encoding::DefaultFuchsiaResourceDialect,
12200 >,
12201 offset: usize,
12202 _depth: fidl::encoding::Depth,
12203 ) -> fidl::Result<()> {
12204 encoder.debug_check_bounds::<AllocatorAllocateSharedCollectionRequest>(offset);
12205 // Delegate to tuple encoding.
12206 fidl::encoding::Encode::<
12207 AllocatorAllocateSharedCollectionRequest,
12208 fidl::encoding::DefaultFuchsiaResourceDialect,
12209 >::encode(
12210 (
12211 <fidl::encoding::Endpoint<
12212 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12213 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12214 &mut self.token_request,
12215 ),
12216 ),
12217 encoder,
12218 offset,
12219 _depth,
12220 )
12221 }
12222 }
12223 unsafe impl<
12224 T0: fidl::encoding::Encode<
12225 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12226 fidl::encoding::DefaultFuchsiaResourceDialect,
12227 >,
12228 >
12229 fidl::encoding::Encode<
12230 AllocatorAllocateSharedCollectionRequest,
12231 fidl::encoding::DefaultFuchsiaResourceDialect,
12232 > for (T0,)
12233 {
12234 #[inline]
12235 unsafe fn encode(
12236 self,
12237 encoder: &mut fidl::encoding::Encoder<
12238 '_,
12239 fidl::encoding::DefaultFuchsiaResourceDialect,
12240 >,
12241 offset: usize,
12242 depth: fidl::encoding::Depth,
12243 ) -> fidl::Result<()> {
12244 encoder.debug_check_bounds::<AllocatorAllocateSharedCollectionRequest>(offset);
12245 // Zero out padding regions. There's no need to apply masks
12246 // because the unmasked parts will be overwritten by fields.
12247 // Write the fields.
12248 self.0.encode(encoder, offset + 0, depth)?;
12249 Ok(())
12250 }
12251 }
12252
12253 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12254 for AllocatorAllocateSharedCollectionRequest
12255 {
12256 #[inline(always)]
12257 fn new_empty() -> Self {
12258 Self {
12259 token_request: fidl::new_empty!(
12260 fidl::encoding::Endpoint<
12261 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12262 >,
12263 fidl::encoding::DefaultFuchsiaResourceDialect
12264 ),
12265 }
12266 }
12267
12268 #[inline]
12269 unsafe fn decode(
12270 &mut self,
12271 decoder: &mut fidl::encoding::Decoder<
12272 '_,
12273 fidl::encoding::DefaultFuchsiaResourceDialect,
12274 >,
12275 offset: usize,
12276 _depth: fidl::encoding::Depth,
12277 ) -> fidl::Result<()> {
12278 decoder.debug_check_bounds::<Self>(offset);
12279 // Verify that padding bytes are zero.
12280 fidl::decode!(
12281 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12282 fidl::encoding::DefaultFuchsiaResourceDialect,
12283 &mut self.token_request,
12284 decoder,
12285 offset + 0,
12286 _depth
12287 )?;
12288 Ok(())
12289 }
12290 }
12291
12292 impl fidl::encoding::ResourceTypeMarker for AllocatorBindSharedCollectionRequest {
12293 type Borrowed<'a> = &'a mut Self;
12294 fn take_or_borrow<'a>(
12295 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12296 ) -> Self::Borrowed<'a> {
12297 value
12298 }
12299 }
12300
12301 unsafe impl fidl::encoding::TypeMarker for AllocatorBindSharedCollectionRequest {
12302 type Owned = Self;
12303
12304 #[inline(always)]
12305 fn inline_align(_context: fidl::encoding::Context) -> usize {
12306 4
12307 }
12308
12309 #[inline(always)]
12310 fn inline_size(_context: fidl::encoding::Context) -> usize {
12311 8
12312 }
12313 }
12314
12315 unsafe impl
12316 fidl::encoding::Encode<
12317 AllocatorBindSharedCollectionRequest,
12318 fidl::encoding::DefaultFuchsiaResourceDialect,
12319 > for &mut AllocatorBindSharedCollectionRequest
12320 {
12321 #[inline]
12322 unsafe fn encode(
12323 self,
12324 encoder: &mut fidl::encoding::Encoder<
12325 '_,
12326 fidl::encoding::DefaultFuchsiaResourceDialect,
12327 >,
12328 offset: usize,
12329 _depth: fidl::encoding::Depth,
12330 ) -> fidl::Result<()> {
12331 encoder.debug_check_bounds::<AllocatorBindSharedCollectionRequest>(offset);
12332 // Delegate to tuple encoding.
12333 fidl::encoding::Encode::<AllocatorBindSharedCollectionRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
12334 (
12335 <fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.token),
12336 <fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffer_collection_request),
12337 ),
12338 encoder, offset, _depth
12339 )
12340 }
12341 }
12342 unsafe impl<
12343 T0: fidl::encoding::Encode<
12344 fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
12345 fidl::encoding::DefaultFuchsiaResourceDialect,
12346 >,
12347 T1: fidl::encoding::Encode<
12348 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12349 fidl::encoding::DefaultFuchsiaResourceDialect,
12350 >,
12351 >
12352 fidl::encoding::Encode<
12353 AllocatorBindSharedCollectionRequest,
12354 fidl::encoding::DefaultFuchsiaResourceDialect,
12355 > for (T0, T1)
12356 {
12357 #[inline]
12358 unsafe fn encode(
12359 self,
12360 encoder: &mut fidl::encoding::Encoder<
12361 '_,
12362 fidl::encoding::DefaultFuchsiaResourceDialect,
12363 >,
12364 offset: usize,
12365 depth: fidl::encoding::Depth,
12366 ) -> fidl::Result<()> {
12367 encoder.debug_check_bounds::<AllocatorBindSharedCollectionRequest>(offset);
12368 // Zero out padding regions. There's no need to apply masks
12369 // because the unmasked parts will be overwritten by fields.
12370 // Write the fields.
12371 self.0.encode(encoder, offset + 0, depth)?;
12372 self.1.encode(encoder, offset + 4, depth)?;
12373 Ok(())
12374 }
12375 }
12376
12377 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12378 for AllocatorBindSharedCollectionRequest
12379 {
12380 #[inline(always)]
12381 fn new_empty() -> Self {
12382 Self {
12383 token: fidl::new_empty!(
12384 fidl::encoding::Endpoint<
12385 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
12386 >,
12387 fidl::encoding::DefaultFuchsiaResourceDialect
12388 ),
12389 buffer_collection_request: fidl::new_empty!(
12390 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12391 fidl::encoding::DefaultFuchsiaResourceDialect
12392 ),
12393 }
12394 }
12395
12396 #[inline]
12397 unsafe fn decode(
12398 &mut self,
12399 decoder: &mut fidl::encoding::Decoder<
12400 '_,
12401 fidl::encoding::DefaultFuchsiaResourceDialect,
12402 >,
12403 offset: usize,
12404 _depth: fidl::encoding::Depth,
12405 ) -> fidl::Result<()> {
12406 decoder.debug_check_bounds::<Self>(offset);
12407 // Verify that padding bytes are zero.
12408 fidl::decode!(
12409 fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
12410 fidl::encoding::DefaultFuchsiaResourceDialect,
12411 &mut self.token,
12412 decoder,
12413 offset + 0,
12414 _depth
12415 )?;
12416 fidl::decode!(
12417 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12418 fidl::encoding::DefaultFuchsiaResourceDialect,
12419 &mut self.buffer_collection_request,
12420 decoder,
12421 offset + 4,
12422 _depth
12423 )?;
12424 Ok(())
12425 }
12426 }
12427
12428 impl fidl::encoding::ResourceTypeMarker for AllocatorConnectToSysmem2AllocatorRequest {
12429 type Borrowed<'a> = &'a mut Self;
12430 fn take_or_borrow<'a>(
12431 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12432 ) -> Self::Borrowed<'a> {
12433 value
12434 }
12435 }
12436
12437 unsafe impl fidl::encoding::TypeMarker for AllocatorConnectToSysmem2AllocatorRequest {
12438 type Owned = Self;
12439
12440 #[inline(always)]
12441 fn inline_align(_context: fidl::encoding::Context) -> usize {
12442 4
12443 }
12444
12445 #[inline(always)]
12446 fn inline_size(_context: fidl::encoding::Context) -> usize {
12447 4
12448 }
12449 }
12450
12451 unsafe impl
12452 fidl::encoding::Encode<
12453 AllocatorConnectToSysmem2AllocatorRequest,
12454 fidl::encoding::DefaultFuchsiaResourceDialect,
12455 > for &mut AllocatorConnectToSysmem2AllocatorRequest
12456 {
12457 #[inline]
12458 unsafe fn encode(
12459 self,
12460 encoder: &mut fidl::encoding::Encoder<
12461 '_,
12462 fidl::encoding::DefaultFuchsiaResourceDialect,
12463 >,
12464 offset: usize,
12465 _depth: fidl::encoding::Depth,
12466 ) -> fidl::Result<()> {
12467 encoder.debug_check_bounds::<AllocatorConnectToSysmem2AllocatorRequest>(offset);
12468 // Delegate to tuple encoding.
12469 fidl::encoding::Encode::<
12470 AllocatorConnectToSysmem2AllocatorRequest,
12471 fidl::encoding::DefaultFuchsiaResourceDialect,
12472 >::encode(
12473 (<fidl::encoding::Endpoint<
12474 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12475 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12476 &mut self.allocator_request,
12477 ),),
12478 encoder,
12479 offset,
12480 _depth,
12481 )
12482 }
12483 }
12484 unsafe impl<
12485 T0: fidl::encoding::Encode<
12486 fidl::encoding::Endpoint<
12487 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12488 >,
12489 fidl::encoding::DefaultFuchsiaResourceDialect,
12490 >,
12491 >
12492 fidl::encoding::Encode<
12493 AllocatorConnectToSysmem2AllocatorRequest,
12494 fidl::encoding::DefaultFuchsiaResourceDialect,
12495 > for (T0,)
12496 {
12497 #[inline]
12498 unsafe fn encode(
12499 self,
12500 encoder: &mut fidl::encoding::Encoder<
12501 '_,
12502 fidl::encoding::DefaultFuchsiaResourceDialect,
12503 >,
12504 offset: usize,
12505 depth: fidl::encoding::Depth,
12506 ) -> fidl::Result<()> {
12507 encoder.debug_check_bounds::<AllocatorConnectToSysmem2AllocatorRequest>(offset);
12508 // Zero out padding regions. There's no need to apply masks
12509 // because the unmasked parts will be overwritten by fields.
12510 // Write the fields.
12511 self.0.encode(encoder, offset + 0, depth)?;
12512 Ok(())
12513 }
12514 }
12515
12516 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12517 for AllocatorConnectToSysmem2AllocatorRequest
12518 {
12519 #[inline(always)]
12520 fn new_empty() -> Self {
12521 Self {
12522 allocator_request: fidl::new_empty!(
12523 fidl::encoding::Endpoint<
12524 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12525 >,
12526 fidl::encoding::DefaultFuchsiaResourceDialect
12527 ),
12528 }
12529 }
12530
12531 #[inline]
12532 unsafe fn decode(
12533 &mut self,
12534 decoder: &mut fidl::encoding::Decoder<
12535 '_,
12536 fidl::encoding::DefaultFuchsiaResourceDialect,
12537 >,
12538 offset: usize,
12539 _depth: fidl::encoding::Depth,
12540 ) -> fidl::Result<()> {
12541 decoder.debug_check_bounds::<Self>(offset);
12542 // Verify that padding bytes are zero.
12543 fidl::decode!(
12544 fidl::encoding::Endpoint<
12545 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12546 >,
12547 fidl::encoding::DefaultFuchsiaResourceDialect,
12548 &mut self.allocator_request,
12549 decoder,
12550 offset + 0,
12551 _depth
12552 )?;
12553 Ok(())
12554 }
12555 }
12556
12557 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
12558 type Borrowed<'a> = &'a mut Self;
12559 fn take_or_borrow<'a>(
12560 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12561 ) -> Self::Borrowed<'a> {
12562 value
12563 }
12564 }
12565
12566 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
12567 type Owned = Self;
12568
12569 #[inline(always)]
12570 fn inline_align(_context: fidl::encoding::Context) -> usize {
12571 4
12572 }
12573
12574 #[inline(always)]
12575 fn inline_size(_context: fidl::encoding::Context) -> usize {
12576 8
12577 }
12578 }
12579
12580 unsafe impl
12581 fidl::encoding::Encode<
12582 BufferCollectionAttachLifetimeTrackingRequest,
12583 fidl::encoding::DefaultFuchsiaResourceDialect,
12584 > for &mut BufferCollectionAttachLifetimeTrackingRequest
12585 {
12586 #[inline]
12587 unsafe fn encode(
12588 self,
12589 encoder: &mut fidl::encoding::Encoder<
12590 '_,
12591 fidl::encoding::DefaultFuchsiaResourceDialect,
12592 >,
12593 offset: usize,
12594 _depth: fidl::encoding::Depth,
12595 ) -> fidl::Result<()> {
12596 encoder.debug_check_bounds::<BufferCollectionAttachLifetimeTrackingRequest>(offset);
12597 // Delegate to tuple encoding.
12598 fidl::encoding::Encode::<
12599 BufferCollectionAttachLifetimeTrackingRequest,
12600 fidl::encoding::DefaultFuchsiaResourceDialect,
12601 >::encode(
12602 (
12603 <fidl::encoding::HandleType<
12604 fidl::EventPair,
12605 { fidl::ObjectType::EVENTPAIR.into_raw() },
12606 2147483648,
12607 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12608 &mut self.server_end
12609 ),
12610 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffers_remaining),
12611 ),
12612 encoder,
12613 offset,
12614 _depth,
12615 )
12616 }
12617 }
12618 unsafe impl<
12619 T0: fidl::encoding::Encode<
12620 fidl::encoding::HandleType<
12621 fidl::EventPair,
12622 { fidl::ObjectType::EVENTPAIR.into_raw() },
12623 2147483648,
12624 >,
12625 fidl::encoding::DefaultFuchsiaResourceDialect,
12626 >,
12627 T1: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12628 >
12629 fidl::encoding::Encode<
12630 BufferCollectionAttachLifetimeTrackingRequest,
12631 fidl::encoding::DefaultFuchsiaResourceDialect,
12632 > for (T0, T1)
12633 {
12634 #[inline]
12635 unsafe fn encode(
12636 self,
12637 encoder: &mut fidl::encoding::Encoder<
12638 '_,
12639 fidl::encoding::DefaultFuchsiaResourceDialect,
12640 >,
12641 offset: usize,
12642 depth: fidl::encoding::Depth,
12643 ) -> fidl::Result<()> {
12644 encoder.debug_check_bounds::<BufferCollectionAttachLifetimeTrackingRequest>(offset);
12645 // Zero out padding regions. There's no need to apply masks
12646 // because the unmasked parts will be overwritten by fields.
12647 // Write the fields.
12648 self.0.encode(encoder, offset + 0, depth)?;
12649 self.1.encode(encoder, offset + 4, depth)?;
12650 Ok(())
12651 }
12652 }
12653
12654 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12655 for BufferCollectionAttachLifetimeTrackingRequest
12656 {
12657 #[inline(always)]
12658 fn new_empty() -> Self {
12659 Self {
12660 server_end: fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
12661 buffers_remaining: fidl::new_empty!(
12662 u32,
12663 fidl::encoding::DefaultFuchsiaResourceDialect
12664 ),
12665 }
12666 }
12667
12668 #[inline]
12669 unsafe fn decode(
12670 &mut self,
12671 decoder: &mut fidl::encoding::Decoder<
12672 '_,
12673 fidl::encoding::DefaultFuchsiaResourceDialect,
12674 >,
12675 offset: usize,
12676 _depth: fidl::encoding::Depth,
12677 ) -> fidl::Result<()> {
12678 decoder.debug_check_bounds::<Self>(offset);
12679 // Verify that padding bytes are zero.
12680 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.server_end, decoder, offset + 0, _depth)?;
12681 fidl::decode!(
12682 u32,
12683 fidl::encoding::DefaultFuchsiaResourceDialect,
12684 &mut self.buffers_remaining,
12685 decoder,
12686 offset + 4,
12687 _depth
12688 )?;
12689 Ok(())
12690 }
12691 }
12692
12693 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachTokenRequest {
12694 type Borrowed<'a> = &'a mut Self;
12695 fn take_or_borrow<'a>(
12696 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12697 ) -> Self::Borrowed<'a> {
12698 value
12699 }
12700 }
12701
12702 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachTokenRequest {
12703 type Owned = Self;
12704
12705 #[inline(always)]
12706 fn inline_align(_context: fidl::encoding::Context) -> usize {
12707 4
12708 }
12709
12710 #[inline(always)]
12711 fn inline_size(_context: fidl::encoding::Context) -> usize {
12712 8
12713 }
12714 }
12715
12716 unsafe impl
12717 fidl::encoding::Encode<
12718 BufferCollectionAttachTokenRequest,
12719 fidl::encoding::DefaultFuchsiaResourceDialect,
12720 > for &mut BufferCollectionAttachTokenRequest
12721 {
12722 #[inline]
12723 unsafe fn encode(
12724 self,
12725 encoder: &mut fidl::encoding::Encoder<
12726 '_,
12727 fidl::encoding::DefaultFuchsiaResourceDialect,
12728 >,
12729 offset: usize,
12730 _depth: fidl::encoding::Depth,
12731 ) -> fidl::Result<()> {
12732 encoder.debug_check_bounds::<BufferCollectionAttachTokenRequest>(offset);
12733 // Delegate to tuple encoding.
12734 fidl::encoding::Encode::<
12735 BufferCollectionAttachTokenRequest,
12736 fidl::encoding::DefaultFuchsiaResourceDialect,
12737 >::encode(
12738 (
12739 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.rights_attenuation_mask),
12740 <fidl::encoding::Endpoint<
12741 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12742 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12743 &mut self.token_request,
12744 ),
12745 ),
12746 encoder,
12747 offset,
12748 _depth,
12749 )
12750 }
12751 }
12752 unsafe impl<
12753 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12754 T1: fidl::encoding::Encode<
12755 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12756 fidl::encoding::DefaultFuchsiaResourceDialect,
12757 >,
12758 >
12759 fidl::encoding::Encode<
12760 BufferCollectionAttachTokenRequest,
12761 fidl::encoding::DefaultFuchsiaResourceDialect,
12762 > for (T0, T1)
12763 {
12764 #[inline]
12765 unsafe fn encode(
12766 self,
12767 encoder: &mut fidl::encoding::Encoder<
12768 '_,
12769 fidl::encoding::DefaultFuchsiaResourceDialect,
12770 >,
12771 offset: usize,
12772 depth: fidl::encoding::Depth,
12773 ) -> fidl::Result<()> {
12774 encoder.debug_check_bounds::<BufferCollectionAttachTokenRequest>(offset);
12775 // Zero out padding regions. There's no need to apply masks
12776 // because the unmasked parts will be overwritten by fields.
12777 // Write the fields.
12778 self.0.encode(encoder, offset + 0, depth)?;
12779 self.1.encode(encoder, offset + 4, depth)?;
12780 Ok(())
12781 }
12782 }
12783
12784 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12785 for BufferCollectionAttachTokenRequest
12786 {
12787 #[inline(always)]
12788 fn new_empty() -> Self {
12789 Self {
12790 rights_attenuation_mask: fidl::new_empty!(
12791 u32,
12792 fidl::encoding::DefaultFuchsiaResourceDialect
12793 ),
12794 token_request: fidl::new_empty!(
12795 fidl::encoding::Endpoint<
12796 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12797 >,
12798 fidl::encoding::DefaultFuchsiaResourceDialect
12799 ),
12800 }
12801 }
12802
12803 #[inline]
12804 unsafe fn decode(
12805 &mut self,
12806 decoder: &mut fidl::encoding::Decoder<
12807 '_,
12808 fidl::encoding::DefaultFuchsiaResourceDialect,
12809 >,
12810 offset: usize,
12811 _depth: fidl::encoding::Depth,
12812 ) -> fidl::Result<()> {
12813 decoder.debug_check_bounds::<Self>(offset);
12814 // Verify that padding bytes are zero.
12815 fidl::decode!(
12816 u32,
12817 fidl::encoding::DefaultFuchsiaResourceDialect,
12818 &mut self.rights_attenuation_mask,
12819 decoder,
12820 offset + 0,
12821 _depth
12822 )?;
12823 fidl::decode!(
12824 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12825 fidl::encoding::DefaultFuchsiaResourceDialect,
12826 &mut self.token_request,
12827 decoder,
12828 offset + 4,
12829 _depth
12830 )?;
12831 Ok(())
12832 }
12833 }
12834
12835 impl fidl::encoding::ResourceTypeMarker for BufferCollectionGetAuxBuffersResponse {
12836 type Borrowed<'a> = &'a mut Self;
12837 fn take_or_borrow<'a>(
12838 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12839 ) -> Self::Borrowed<'a> {
12840 value
12841 }
12842 }
12843
12844 unsafe impl fidl::encoding::TypeMarker for BufferCollectionGetAuxBuffersResponse {
12845 type Owned = Self;
12846
12847 #[inline(always)]
12848 fn inline_align(_context: fidl::encoding::Context) -> usize {
12849 8
12850 }
12851
12852 #[inline(always)]
12853 fn inline_size(_context: fidl::encoding::Context) -> usize {
12854 1304
12855 }
12856 }
12857
12858 unsafe impl
12859 fidl::encoding::Encode<
12860 BufferCollectionGetAuxBuffersResponse,
12861 fidl::encoding::DefaultFuchsiaResourceDialect,
12862 > for &mut BufferCollectionGetAuxBuffersResponse
12863 {
12864 #[inline]
12865 unsafe fn encode(
12866 self,
12867 encoder: &mut fidl::encoding::Encoder<
12868 '_,
12869 fidl::encoding::DefaultFuchsiaResourceDialect,
12870 >,
12871 offset: usize,
12872 _depth: fidl::encoding::Depth,
12873 ) -> fidl::Result<()> {
12874 encoder.debug_check_bounds::<BufferCollectionGetAuxBuffersResponse>(offset);
12875 // Delegate to tuple encoding.
12876 fidl::encoding::Encode::<
12877 BufferCollectionGetAuxBuffersResponse,
12878 fidl::encoding::DefaultFuchsiaResourceDialect,
12879 >::encode(
12880 (
12881 <i32 as fidl::encoding::ValueTypeMarker>::borrow(&self.status),
12882 <BufferCollectionInfo2 as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12883 &mut self.buffer_collection_info_aux_buffers,
12884 ),
12885 ),
12886 encoder,
12887 offset,
12888 _depth,
12889 )
12890 }
12891 }
12892 unsafe impl<
12893 T0: fidl::encoding::Encode<i32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12894 T1: fidl::encoding::Encode<
12895 BufferCollectionInfo2,
12896 fidl::encoding::DefaultFuchsiaResourceDialect,
12897 >,
12898 >
12899 fidl::encoding::Encode<
12900 BufferCollectionGetAuxBuffersResponse,
12901 fidl::encoding::DefaultFuchsiaResourceDialect,
12902 > for (T0, T1)
12903 {
12904 #[inline]
12905 unsafe fn encode(
12906 self,
12907 encoder: &mut fidl::encoding::Encoder<
12908 '_,
12909 fidl::encoding::DefaultFuchsiaResourceDialect,
12910 >,
12911 offset: usize,
12912 depth: fidl::encoding::Depth,
12913 ) -> fidl::Result<()> {
12914 encoder.debug_check_bounds::<BufferCollectionGetAuxBuffersResponse>(offset);
12915 // Zero out padding regions. There's no need to apply masks
12916 // because the unmasked parts will be overwritten by fields.
12917 unsafe {
12918 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
12919 (ptr as *mut u64).write_unaligned(0);
12920 }
12921 // Write the fields.
12922 self.0.encode(encoder, offset + 0, depth)?;
12923 self.1.encode(encoder, offset + 8, depth)?;
12924 Ok(())
12925 }
12926 }
12927
12928 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12929 for BufferCollectionGetAuxBuffersResponse
12930 {
12931 #[inline(always)]
12932 fn new_empty() -> Self {
12933 Self {
12934 status: fidl::new_empty!(i32, fidl::encoding::DefaultFuchsiaResourceDialect),
12935 buffer_collection_info_aux_buffers: fidl::new_empty!(
12936 BufferCollectionInfo2,
12937 fidl::encoding::DefaultFuchsiaResourceDialect
12938 ),
12939 }
12940 }
12941
12942 #[inline]
12943 unsafe fn decode(
12944 &mut self,
12945 decoder: &mut fidl::encoding::Decoder<
12946 '_,
12947 fidl::encoding::DefaultFuchsiaResourceDialect,
12948 >,
12949 offset: usize,
12950 _depth: fidl::encoding::Depth,
12951 ) -> fidl::Result<()> {
12952 decoder.debug_check_bounds::<Self>(offset);
12953 // Verify that padding bytes are zero.
12954 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
12955 let padval = unsafe { (ptr as *const u64).read_unaligned() };
12956 let mask = 0xffffffff00000000u64;
12957 let maskedval = padval & mask;
12958 if maskedval != 0 {
12959 return Err(fidl::Error::NonZeroPadding {
12960 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
12961 });
12962 }
12963 fidl::decode!(
12964 i32,
12965 fidl::encoding::DefaultFuchsiaResourceDialect,
12966 &mut self.status,
12967 decoder,
12968 offset + 0,
12969 _depth
12970 )?;
12971 fidl::decode!(
12972 BufferCollectionInfo2,
12973 fidl::encoding::DefaultFuchsiaResourceDialect,
12974 &mut self.buffer_collection_info_aux_buffers,
12975 decoder,
12976 offset + 8,
12977 _depth
12978 )?;
12979 Ok(())
12980 }
12981 }
12982
12983 impl fidl::encoding::ResourceTypeMarker for BufferCollectionInfo {
12984 type Borrowed<'a> = &'a mut Self;
12985 fn take_or_borrow<'a>(
12986 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12987 ) -> Self::Borrowed<'a> {
12988 value
12989 }
12990 }
12991
12992 unsafe impl fidl::encoding::TypeMarker for BufferCollectionInfo {
12993 type Owned = Self;
12994
12995 #[inline(always)]
12996 fn inline_align(_context: fidl::encoding::Context) -> usize {
12997 8
12998 }
12999
13000 #[inline(always)]
13001 fn inline_size(_context: fidl::encoding::Context) -> usize {
13002 352
13003 }
13004 }
13005
13006 unsafe impl
13007 fidl::encoding::Encode<BufferCollectionInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
13008 for &mut BufferCollectionInfo
13009 {
13010 #[inline]
13011 unsafe fn encode(
13012 self,
13013 encoder: &mut fidl::encoding::Encoder<
13014 '_,
13015 fidl::encoding::DefaultFuchsiaResourceDialect,
13016 >,
13017 offset: usize,
13018 _depth: fidl::encoding::Depth,
13019 ) -> fidl::Result<()> {
13020 encoder.debug_check_bounds::<BufferCollectionInfo>(offset);
13021 // Delegate to tuple encoding.
13022 fidl::encoding::Encode::<
13023 BufferCollectionInfo,
13024 fidl::encoding::DefaultFuchsiaResourceDialect,
13025 >::encode(
13026 (
13027 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffer_count),
13028 <BufferFormat as fidl::encoding::ValueTypeMarker>::borrow(&self.format),
13029 <fidl::encoding::Array<
13030 fidl::encoding::Optional<
13031 fidl::encoding::HandleType<
13032 fidl::Vmo,
13033 { fidl::ObjectType::VMO.into_raw() },
13034 2147483648,
13035 >,
13036 >,
13037 64,
13038 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13039 &mut self.vmos
13040 ),
13041 <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.vmo_size),
13042 ),
13043 encoder,
13044 offset,
13045 _depth,
13046 )
13047 }
13048 }
13049 unsafe impl<
13050 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13051 T1: fidl::encoding::Encode<BufferFormat, fidl::encoding::DefaultFuchsiaResourceDialect>,
13052 T2: fidl::encoding::Encode<
13053 fidl::encoding::Array<
13054 fidl::encoding::Optional<
13055 fidl::encoding::HandleType<
13056 fidl::Vmo,
13057 { fidl::ObjectType::VMO.into_raw() },
13058 2147483648,
13059 >,
13060 >,
13061 64,
13062 >,
13063 fidl::encoding::DefaultFuchsiaResourceDialect,
13064 >,
13065 T3: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
13066 >
13067 fidl::encoding::Encode<BufferCollectionInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
13068 for (T0, T1, T2, T3)
13069 {
13070 #[inline]
13071 unsafe fn encode(
13072 self,
13073 encoder: &mut fidl::encoding::Encoder<
13074 '_,
13075 fidl::encoding::DefaultFuchsiaResourceDialect,
13076 >,
13077 offset: usize,
13078 depth: fidl::encoding::Depth,
13079 ) -> fidl::Result<()> {
13080 encoder.debug_check_bounds::<BufferCollectionInfo>(offset);
13081 // Zero out padding regions. There's no need to apply masks
13082 // because the unmasked parts will be overwritten by fields.
13083 unsafe {
13084 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
13085 (ptr as *mut u64).write_unaligned(0);
13086 }
13087 // Write the fields.
13088 self.0.encode(encoder, offset + 0, depth)?;
13089 self.1.encode(encoder, offset + 8, depth)?;
13090 self.2.encode(encoder, offset + 88, depth)?;
13091 self.3.encode(encoder, offset + 344, depth)?;
13092 Ok(())
13093 }
13094 }
13095
13096 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13097 for BufferCollectionInfo
13098 {
13099 #[inline(always)]
13100 fn new_empty() -> Self {
13101 Self {
13102 buffer_count: fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect),
13103 format: fidl::new_empty!(
13104 BufferFormat,
13105 fidl::encoding::DefaultFuchsiaResourceDialect
13106 ),
13107 vmos: fidl::new_empty!(
13108 fidl::encoding::Array<
13109 fidl::encoding::Optional<
13110 fidl::encoding::HandleType<
13111 fidl::Vmo,
13112 { fidl::ObjectType::VMO.into_raw() },
13113 2147483648,
13114 >,
13115 >,
13116 64,
13117 >,
13118 fidl::encoding::DefaultFuchsiaResourceDialect
13119 ),
13120 vmo_size: fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect),
13121 }
13122 }
13123
13124 #[inline]
13125 unsafe fn decode(
13126 &mut self,
13127 decoder: &mut fidl::encoding::Decoder<
13128 '_,
13129 fidl::encoding::DefaultFuchsiaResourceDialect,
13130 >,
13131 offset: usize,
13132 _depth: fidl::encoding::Depth,
13133 ) -> fidl::Result<()> {
13134 decoder.debug_check_bounds::<Self>(offset);
13135 // Verify that padding bytes are zero.
13136 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
13137 let padval = unsafe { (ptr as *const u64).read_unaligned() };
13138 let mask = 0xffffffff00000000u64;
13139 let maskedval = padval & mask;
13140 if maskedval != 0 {
13141 return Err(fidl::Error::NonZeroPadding {
13142 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
13143 });
13144 }
13145 fidl::decode!(
13146 u32,
13147 fidl::encoding::DefaultFuchsiaResourceDialect,
13148 &mut self.buffer_count,
13149 decoder,
13150 offset + 0,
13151 _depth
13152 )?;
13153 fidl::decode!(
13154 BufferFormat,
13155 fidl::encoding::DefaultFuchsiaResourceDialect,
13156 &mut self.format,
13157 decoder,
13158 offset + 8,
13159 _depth
13160 )?;
13161 fidl::decode!(
13162 fidl::encoding::Array<
13163 fidl::encoding::Optional<
13164 fidl::encoding::HandleType<
13165 fidl::Vmo,
13166 { fidl::ObjectType::VMO.into_raw() },
13167 2147483648,
13168 >,
13169 >,
13170 64,
13171 >,
13172 fidl::encoding::DefaultFuchsiaResourceDialect,
13173 &mut self.vmos,
13174 decoder,
13175 offset + 88,
13176 _depth
13177 )?;
13178 fidl::decode!(
13179 u64,
13180 fidl::encoding::DefaultFuchsiaResourceDialect,
13181 &mut self.vmo_size,
13182 decoder,
13183 offset + 344,
13184 _depth
13185 )?;
13186 Ok(())
13187 }
13188 }
13189
13190 impl fidl::encoding::ResourceTypeMarker for BufferCollectionInfo2 {
13191 type Borrowed<'a> = &'a mut Self;
13192 fn take_or_borrow<'a>(
13193 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13194 ) -> Self::Borrowed<'a> {
13195 value
13196 }
13197 }
13198
13199 unsafe impl fidl::encoding::TypeMarker for BufferCollectionInfo2 {
13200 type Owned = Self;
13201
13202 #[inline(always)]
13203 fn inline_align(_context: fidl::encoding::Context) -> usize {
13204 8
13205 }
13206
13207 #[inline(always)]
13208 fn inline_size(_context: fidl::encoding::Context) -> usize {
13209 1296
13210 }
13211 }
13212
13213 unsafe impl
13214 fidl::encoding::Encode<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>
13215 for &mut BufferCollectionInfo2
13216 {
13217 #[inline]
13218 unsafe fn encode(
13219 self,
13220 encoder: &mut fidl::encoding::Encoder<
13221 '_,
13222 fidl::encoding::DefaultFuchsiaResourceDialect,
13223 >,
13224 offset: usize,
13225 _depth: fidl::encoding::Depth,
13226 ) -> fidl::Result<()> {
13227 encoder.debug_check_bounds::<BufferCollectionInfo2>(offset);
13228 // Delegate to tuple encoding.
13229 fidl::encoding::Encode::<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
13230 (
13231 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffer_count),
13232 <SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow(&self.settings),
13233 <fidl::encoding::Array<VmoBuffer, 64> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffers),
13234 ),
13235 encoder, offset, _depth
13236 )
13237 }
13238 }
13239 unsafe impl<
13240 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13241 T1: fidl::encoding::Encode<
13242 SingleBufferSettings,
13243 fidl::encoding::DefaultFuchsiaResourceDialect,
13244 >,
13245 T2: fidl::encoding::Encode<
13246 fidl::encoding::Array<VmoBuffer, 64>,
13247 fidl::encoding::DefaultFuchsiaResourceDialect,
13248 >,
13249 >
13250 fidl::encoding::Encode<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>
13251 for (T0, T1, T2)
13252 {
13253 #[inline]
13254 unsafe fn encode(
13255 self,
13256 encoder: &mut fidl::encoding::Encoder<
13257 '_,
13258 fidl::encoding::DefaultFuchsiaResourceDialect,
13259 >,
13260 offset: usize,
13261 depth: fidl::encoding::Depth,
13262 ) -> fidl::Result<()> {
13263 encoder.debug_check_bounds::<BufferCollectionInfo2>(offset);
13264 // Zero out padding regions. There's no need to apply masks
13265 // because the unmasked parts will be overwritten by fields.
13266 unsafe {
13267 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
13268 (ptr as *mut u64).write_unaligned(0);
13269 }
13270 // Write the fields.
13271 self.0.encode(encoder, offset + 0, depth)?;
13272 self.1.encode(encoder, offset + 8, depth)?;
13273 self.2.encode(encoder, offset + 272, depth)?;
13274 Ok(())
13275 }
13276 }
13277
13278 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13279 for BufferCollectionInfo2
13280 {
13281 #[inline(always)]
13282 fn new_empty() -> Self {
13283 Self {
13284 buffer_count: fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect),
13285 settings: fidl::new_empty!(
13286 SingleBufferSettings,
13287 fidl::encoding::DefaultFuchsiaResourceDialect
13288 ),
13289 buffers: fidl::new_empty!(fidl::encoding::Array<VmoBuffer, 64>, fidl::encoding::DefaultFuchsiaResourceDialect),
13290 }
13291 }
13292
13293 #[inline]
13294 unsafe fn decode(
13295 &mut self,
13296 decoder: &mut fidl::encoding::Decoder<
13297 '_,
13298 fidl::encoding::DefaultFuchsiaResourceDialect,
13299 >,
13300 offset: usize,
13301 _depth: fidl::encoding::Depth,
13302 ) -> fidl::Result<()> {
13303 decoder.debug_check_bounds::<Self>(offset);
13304 // Verify that padding bytes are zero.
13305 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
13306 let padval = unsafe { (ptr as *const u64).read_unaligned() };
13307 let mask = 0xffffffff00000000u64;
13308 let maskedval = padval & mask;
13309 if maskedval != 0 {
13310 return Err(fidl::Error::NonZeroPadding {
13311 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
13312 });
13313 }
13314 fidl::decode!(
13315 u32,
13316 fidl::encoding::DefaultFuchsiaResourceDialect,
13317 &mut self.buffer_count,
13318 decoder,
13319 offset + 0,
13320 _depth
13321 )?;
13322 fidl::decode!(
13323 SingleBufferSettings,
13324 fidl::encoding::DefaultFuchsiaResourceDialect,
13325 &mut self.settings,
13326 decoder,
13327 offset + 8,
13328 _depth
13329 )?;
13330 fidl::decode!(fidl::encoding::Array<VmoBuffer, 64>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.buffers, decoder, offset + 272, _depth)?;
13331 Ok(())
13332 }
13333 }
13334
13335 impl fidl::encoding::ResourceTypeMarker
13336 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13337 {
13338 type Borrowed<'a> = &'a mut Self;
13339 fn take_or_borrow<'a>(
13340 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13341 ) -> Self::Borrowed<'a> {
13342 value
13343 }
13344 }
13345
13346 unsafe impl fidl::encoding::TypeMarker
13347 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13348 {
13349 type Owned = Self;
13350
13351 #[inline(always)]
13352 fn inline_align(_context: fidl::encoding::Context) -> usize {
13353 4
13354 }
13355
13356 #[inline(always)]
13357 fn inline_size(_context: fidl::encoding::Context) -> usize {
13358 4
13359 }
13360 }
13361
13362 unsafe impl
13363 fidl::encoding::Encode<
13364 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13365 fidl::encoding::DefaultFuchsiaResourceDialect,
13366 > for &mut BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13367 {
13368 #[inline]
13369 unsafe fn encode(
13370 self,
13371 encoder: &mut fidl::encoding::Encoder<
13372 '_,
13373 fidl::encoding::DefaultFuchsiaResourceDialect,
13374 >,
13375 offset: usize,
13376 _depth: fidl::encoding::Depth,
13377 ) -> fidl::Result<()> {
13378 encoder
13379 .debug_check_bounds::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
13380 offset,
13381 );
13382 // Delegate to tuple encoding.
13383 fidl::encoding::Encode::<
13384 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13385 fidl::encoding::DefaultFuchsiaResourceDialect,
13386 >::encode(
13387 (<fidl::encoding::Endpoint<
13388 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13389 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13390 &mut self.group_request
13391 ),),
13392 encoder,
13393 offset,
13394 _depth,
13395 )
13396 }
13397 }
13398 unsafe impl<
13399 T0: fidl::encoding::Encode<
13400 fidl::encoding::Endpoint<
13401 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13402 >,
13403 fidl::encoding::DefaultFuchsiaResourceDialect,
13404 >,
13405 >
13406 fidl::encoding::Encode<
13407 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13408 fidl::encoding::DefaultFuchsiaResourceDialect,
13409 > for (T0,)
13410 {
13411 #[inline]
13412 unsafe fn encode(
13413 self,
13414 encoder: &mut fidl::encoding::Encoder<
13415 '_,
13416 fidl::encoding::DefaultFuchsiaResourceDialect,
13417 >,
13418 offset: usize,
13419 depth: fidl::encoding::Depth,
13420 ) -> fidl::Result<()> {
13421 encoder
13422 .debug_check_bounds::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
13423 offset,
13424 );
13425 // Zero out padding regions. There's no need to apply masks
13426 // because the unmasked parts will be overwritten by fields.
13427 // Write the fields.
13428 self.0.encode(encoder, offset + 0, depth)?;
13429 Ok(())
13430 }
13431 }
13432
13433 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13434 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13435 {
13436 #[inline(always)]
13437 fn new_empty() -> Self {
13438 Self {
13439 group_request: fidl::new_empty!(
13440 fidl::encoding::Endpoint<
13441 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13442 >,
13443 fidl::encoding::DefaultFuchsiaResourceDialect
13444 ),
13445 }
13446 }
13447
13448 #[inline]
13449 unsafe fn decode(
13450 &mut self,
13451 decoder: &mut fidl::encoding::Decoder<
13452 '_,
13453 fidl::encoding::DefaultFuchsiaResourceDialect,
13454 >,
13455 offset: usize,
13456 _depth: fidl::encoding::Depth,
13457 ) -> fidl::Result<()> {
13458 decoder.debug_check_bounds::<Self>(offset);
13459 // Verify that padding bytes are zero.
13460 fidl::decode!(
13461 fidl::encoding::Endpoint<
13462 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13463 >,
13464 fidl::encoding::DefaultFuchsiaResourceDialect,
13465 &mut self.group_request,
13466 decoder,
13467 offset + 0,
13468 _depth
13469 )?;
13470 Ok(())
13471 }
13472 }
13473
13474 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateRequest {
13475 type Borrowed<'a> = &'a mut Self;
13476 fn take_or_borrow<'a>(
13477 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13478 ) -> Self::Borrowed<'a> {
13479 value
13480 }
13481 }
13482
13483 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateRequest {
13484 type Owned = Self;
13485
13486 #[inline(always)]
13487 fn inline_align(_context: fidl::encoding::Context) -> usize {
13488 4
13489 }
13490
13491 #[inline(always)]
13492 fn inline_size(_context: fidl::encoding::Context) -> usize {
13493 8
13494 }
13495 }
13496
13497 unsafe impl
13498 fidl::encoding::Encode<
13499 BufferCollectionTokenDuplicateRequest,
13500 fidl::encoding::DefaultFuchsiaResourceDialect,
13501 > for &mut BufferCollectionTokenDuplicateRequest
13502 {
13503 #[inline]
13504 unsafe fn encode(
13505 self,
13506 encoder: &mut fidl::encoding::Encoder<
13507 '_,
13508 fidl::encoding::DefaultFuchsiaResourceDialect,
13509 >,
13510 offset: usize,
13511 _depth: fidl::encoding::Depth,
13512 ) -> fidl::Result<()> {
13513 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateRequest>(offset);
13514 // Delegate to tuple encoding.
13515 fidl::encoding::Encode::<
13516 BufferCollectionTokenDuplicateRequest,
13517 fidl::encoding::DefaultFuchsiaResourceDialect,
13518 >::encode(
13519 (
13520 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.rights_attenuation_mask),
13521 <fidl::encoding::Endpoint<
13522 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
13523 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13524 &mut self.token_request,
13525 ),
13526 ),
13527 encoder,
13528 offset,
13529 _depth,
13530 )
13531 }
13532 }
13533 unsafe impl<
13534 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13535 T1: fidl::encoding::Encode<
13536 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
13537 fidl::encoding::DefaultFuchsiaResourceDialect,
13538 >,
13539 >
13540 fidl::encoding::Encode<
13541 BufferCollectionTokenDuplicateRequest,
13542 fidl::encoding::DefaultFuchsiaResourceDialect,
13543 > for (T0, T1)
13544 {
13545 #[inline]
13546 unsafe fn encode(
13547 self,
13548 encoder: &mut fidl::encoding::Encoder<
13549 '_,
13550 fidl::encoding::DefaultFuchsiaResourceDialect,
13551 >,
13552 offset: usize,
13553 depth: fidl::encoding::Depth,
13554 ) -> fidl::Result<()> {
13555 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateRequest>(offset);
13556 // Zero out padding regions. There's no need to apply masks
13557 // because the unmasked parts will be overwritten by fields.
13558 // Write the fields.
13559 self.0.encode(encoder, offset + 0, depth)?;
13560 self.1.encode(encoder, offset + 4, depth)?;
13561 Ok(())
13562 }
13563 }
13564
13565 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13566 for BufferCollectionTokenDuplicateRequest
13567 {
13568 #[inline(always)]
13569 fn new_empty() -> Self {
13570 Self {
13571 rights_attenuation_mask: fidl::new_empty!(
13572 u32,
13573 fidl::encoding::DefaultFuchsiaResourceDialect
13574 ),
13575 token_request: fidl::new_empty!(
13576 fidl::encoding::Endpoint<
13577 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
13578 >,
13579 fidl::encoding::DefaultFuchsiaResourceDialect
13580 ),
13581 }
13582 }
13583
13584 #[inline]
13585 unsafe fn decode(
13586 &mut self,
13587 decoder: &mut fidl::encoding::Decoder<
13588 '_,
13589 fidl::encoding::DefaultFuchsiaResourceDialect,
13590 >,
13591 offset: usize,
13592 _depth: fidl::encoding::Depth,
13593 ) -> fidl::Result<()> {
13594 decoder.debug_check_bounds::<Self>(offset);
13595 // Verify that padding bytes are zero.
13596 fidl::decode!(
13597 u32,
13598 fidl::encoding::DefaultFuchsiaResourceDialect,
13599 &mut self.rights_attenuation_mask,
13600 decoder,
13601 offset + 0,
13602 _depth
13603 )?;
13604 fidl::decode!(
13605 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
13606 fidl::encoding::DefaultFuchsiaResourceDialect,
13607 &mut self.token_request,
13608 decoder,
13609 offset + 4,
13610 _depth
13611 )?;
13612 Ok(())
13613 }
13614 }
13615
13616 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateSyncResponse {
13617 type Borrowed<'a> = &'a mut Self;
13618 fn take_or_borrow<'a>(
13619 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13620 ) -> Self::Borrowed<'a> {
13621 value
13622 }
13623 }
13624
13625 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateSyncResponse {
13626 type Owned = Self;
13627
13628 #[inline(always)]
13629 fn inline_align(_context: fidl::encoding::Context) -> usize {
13630 8
13631 }
13632
13633 #[inline(always)]
13634 fn inline_size(_context: fidl::encoding::Context) -> usize {
13635 16
13636 }
13637 }
13638
13639 unsafe impl
13640 fidl::encoding::Encode<
13641 BufferCollectionTokenDuplicateSyncResponse,
13642 fidl::encoding::DefaultFuchsiaResourceDialect,
13643 > for &mut BufferCollectionTokenDuplicateSyncResponse
13644 {
13645 #[inline]
13646 unsafe fn encode(
13647 self,
13648 encoder: &mut fidl::encoding::Encoder<
13649 '_,
13650 fidl::encoding::DefaultFuchsiaResourceDialect,
13651 >,
13652 offset: usize,
13653 _depth: fidl::encoding::Depth,
13654 ) -> fidl::Result<()> {
13655 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateSyncResponse>(offset);
13656 // Delegate to tuple encoding.
13657 fidl::encoding::Encode::<
13658 BufferCollectionTokenDuplicateSyncResponse,
13659 fidl::encoding::DefaultFuchsiaResourceDialect,
13660 >::encode(
13661 (<fidl::encoding::Vector<
13662 fidl::encoding::Endpoint<
13663 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13664 >,
13665 64,
13666 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13667 &mut self.tokens
13668 ),),
13669 encoder,
13670 offset,
13671 _depth,
13672 )
13673 }
13674 }
13675 unsafe impl<
13676 T0: fidl::encoding::Encode<
13677 fidl::encoding::Vector<
13678 fidl::encoding::Endpoint<
13679 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13680 >,
13681 64,
13682 >,
13683 fidl::encoding::DefaultFuchsiaResourceDialect,
13684 >,
13685 >
13686 fidl::encoding::Encode<
13687 BufferCollectionTokenDuplicateSyncResponse,
13688 fidl::encoding::DefaultFuchsiaResourceDialect,
13689 > for (T0,)
13690 {
13691 #[inline]
13692 unsafe fn encode(
13693 self,
13694 encoder: &mut fidl::encoding::Encoder<
13695 '_,
13696 fidl::encoding::DefaultFuchsiaResourceDialect,
13697 >,
13698 offset: usize,
13699 depth: fidl::encoding::Depth,
13700 ) -> fidl::Result<()> {
13701 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateSyncResponse>(offset);
13702 // Zero out padding regions. There's no need to apply masks
13703 // because the unmasked parts will be overwritten by fields.
13704 // Write the fields.
13705 self.0.encode(encoder, offset + 0, depth)?;
13706 Ok(())
13707 }
13708 }
13709
13710 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13711 for BufferCollectionTokenDuplicateSyncResponse
13712 {
13713 #[inline(always)]
13714 fn new_empty() -> Self {
13715 Self {
13716 tokens: fidl::new_empty!(
13717 fidl::encoding::Vector<
13718 fidl::encoding::Endpoint<
13719 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13720 >,
13721 64,
13722 >,
13723 fidl::encoding::DefaultFuchsiaResourceDialect
13724 ),
13725 }
13726 }
13727
13728 #[inline]
13729 unsafe fn decode(
13730 &mut self,
13731 decoder: &mut fidl::encoding::Decoder<
13732 '_,
13733 fidl::encoding::DefaultFuchsiaResourceDialect,
13734 >,
13735 offset: usize,
13736 _depth: fidl::encoding::Depth,
13737 ) -> fidl::Result<()> {
13738 decoder.debug_check_bounds::<Self>(offset);
13739 // Verify that padding bytes are zero.
13740 fidl::decode!(
13741 fidl::encoding::Vector<
13742 fidl::encoding::Endpoint<
13743 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13744 >,
13745 64,
13746 >,
13747 fidl::encoding::DefaultFuchsiaResourceDialect,
13748 &mut self.tokens,
13749 decoder,
13750 offset + 0,
13751 _depth
13752 )?;
13753 Ok(())
13754 }
13755 }
13756
13757 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
13758 type Borrowed<'a> = &'a mut Self;
13759 fn take_or_borrow<'a>(
13760 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13761 ) -> Self::Borrowed<'a> {
13762 value
13763 }
13764 }
13765
13766 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
13767 type Owned = Self;
13768
13769 #[inline(always)]
13770 fn inline_align(_context: fidl::encoding::Context) -> usize {
13771 8
13772 }
13773
13774 #[inline(always)]
13775 fn inline_size(_context: fidl::encoding::Context) -> usize {
13776 16
13777 }
13778 }
13779
13780 unsafe impl
13781 fidl::encoding::Encode<
13782 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13783 fidl::encoding::DefaultFuchsiaResourceDialect,
13784 > for &mut BufferCollectionTokenGroupCreateChildrenSyncResponse
13785 {
13786 #[inline]
13787 unsafe fn encode(
13788 self,
13789 encoder: &mut fidl::encoding::Encoder<
13790 '_,
13791 fidl::encoding::DefaultFuchsiaResourceDialect,
13792 >,
13793 offset: usize,
13794 _depth: fidl::encoding::Depth,
13795 ) -> fidl::Result<()> {
13796 encoder
13797 .debug_check_bounds::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(offset);
13798 // Delegate to tuple encoding.
13799 fidl::encoding::Encode::<
13800 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13801 fidl::encoding::DefaultFuchsiaResourceDialect,
13802 >::encode(
13803 (<fidl::encoding::Vector<
13804 fidl::encoding::Endpoint<
13805 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13806 >,
13807 64,
13808 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13809 &mut self.tokens
13810 ),),
13811 encoder,
13812 offset,
13813 _depth,
13814 )
13815 }
13816 }
13817 unsafe impl<
13818 T0: fidl::encoding::Encode<
13819 fidl::encoding::Vector<
13820 fidl::encoding::Endpoint<
13821 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13822 >,
13823 64,
13824 >,
13825 fidl::encoding::DefaultFuchsiaResourceDialect,
13826 >,
13827 >
13828 fidl::encoding::Encode<
13829 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13830 fidl::encoding::DefaultFuchsiaResourceDialect,
13831 > for (T0,)
13832 {
13833 #[inline]
13834 unsafe fn encode(
13835 self,
13836 encoder: &mut fidl::encoding::Encoder<
13837 '_,
13838 fidl::encoding::DefaultFuchsiaResourceDialect,
13839 >,
13840 offset: usize,
13841 depth: fidl::encoding::Depth,
13842 ) -> fidl::Result<()> {
13843 encoder
13844 .debug_check_bounds::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(offset);
13845 // Zero out padding regions. There's no need to apply masks
13846 // because the unmasked parts will be overwritten by fields.
13847 // Write the fields.
13848 self.0.encode(encoder, offset + 0, depth)?;
13849 Ok(())
13850 }
13851 }
13852
13853 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13854 for BufferCollectionTokenGroupCreateChildrenSyncResponse
13855 {
13856 #[inline(always)]
13857 fn new_empty() -> Self {
13858 Self {
13859 tokens: fidl::new_empty!(
13860 fidl::encoding::Vector<
13861 fidl::encoding::Endpoint<
13862 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13863 >,
13864 64,
13865 >,
13866 fidl::encoding::DefaultFuchsiaResourceDialect
13867 ),
13868 }
13869 }
13870
13871 #[inline]
13872 unsafe fn decode(
13873 &mut self,
13874 decoder: &mut fidl::encoding::Decoder<
13875 '_,
13876 fidl::encoding::DefaultFuchsiaResourceDialect,
13877 >,
13878 offset: usize,
13879 _depth: fidl::encoding::Depth,
13880 ) -> fidl::Result<()> {
13881 decoder.debug_check_bounds::<Self>(offset);
13882 // Verify that padding bytes are zero.
13883 fidl::decode!(
13884 fidl::encoding::Vector<
13885 fidl::encoding::Endpoint<
13886 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13887 >,
13888 64,
13889 >,
13890 fidl::encoding::DefaultFuchsiaResourceDialect,
13891 &mut self.tokens,
13892 decoder,
13893 offset + 0,
13894 _depth
13895 )?;
13896 Ok(())
13897 }
13898 }
13899
13900 impl fidl::encoding::ResourceTypeMarker for BufferCollectionWaitForBuffersAllocatedResponse {
13901 type Borrowed<'a> = &'a mut Self;
13902 fn take_or_borrow<'a>(
13903 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13904 ) -> Self::Borrowed<'a> {
13905 value
13906 }
13907 }
13908
13909 unsafe impl fidl::encoding::TypeMarker for BufferCollectionWaitForBuffersAllocatedResponse {
13910 type Owned = Self;
13911
13912 #[inline(always)]
13913 fn inline_align(_context: fidl::encoding::Context) -> usize {
13914 8
13915 }
13916
13917 #[inline(always)]
13918 fn inline_size(_context: fidl::encoding::Context) -> usize {
13919 1304
13920 }
13921 }
13922
13923 unsafe impl
13924 fidl::encoding::Encode<
13925 BufferCollectionWaitForBuffersAllocatedResponse,
13926 fidl::encoding::DefaultFuchsiaResourceDialect,
13927 > for &mut BufferCollectionWaitForBuffersAllocatedResponse
13928 {
13929 #[inline]
13930 unsafe fn encode(
13931 self,
13932 encoder: &mut fidl::encoding::Encoder<
13933 '_,
13934 fidl::encoding::DefaultFuchsiaResourceDialect,
13935 >,
13936 offset: usize,
13937 _depth: fidl::encoding::Depth,
13938 ) -> fidl::Result<()> {
13939 encoder.debug_check_bounds::<BufferCollectionWaitForBuffersAllocatedResponse>(offset);
13940 // Delegate to tuple encoding.
13941 fidl::encoding::Encode::<
13942 BufferCollectionWaitForBuffersAllocatedResponse,
13943 fidl::encoding::DefaultFuchsiaResourceDialect,
13944 >::encode(
13945 (
13946 <i32 as fidl::encoding::ValueTypeMarker>::borrow(&self.status),
13947 <BufferCollectionInfo2 as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13948 &mut self.buffer_collection_info,
13949 ),
13950 ),
13951 encoder,
13952 offset,
13953 _depth,
13954 )
13955 }
13956 }
13957 unsafe impl<
13958 T0: fidl::encoding::Encode<i32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13959 T1: fidl::encoding::Encode<
13960 BufferCollectionInfo2,
13961 fidl::encoding::DefaultFuchsiaResourceDialect,
13962 >,
13963 >
13964 fidl::encoding::Encode<
13965 BufferCollectionWaitForBuffersAllocatedResponse,
13966 fidl::encoding::DefaultFuchsiaResourceDialect,
13967 > for (T0, T1)
13968 {
13969 #[inline]
13970 unsafe fn encode(
13971 self,
13972 encoder: &mut fidl::encoding::Encoder<
13973 '_,
13974 fidl::encoding::DefaultFuchsiaResourceDialect,
13975 >,
13976 offset: usize,
13977 depth: fidl::encoding::Depth,
13978 ) -> fidl::Result<()> {
13979 encoder.debug_check_bounds::<BufferCollectionWaitForBuffersAllocatedResponse>(offset);
13980 // Zero out padding regions. There's no need to apply masks
13981 // because the unmasked parts will be overwritten by fields.
13982 unsafe {
13983 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
13984 (ptr as *mut u64).write_unaligned(0);
13985 }
13986 // Write the fields.
13987 self.0.encode(encoder, offset + 0, depth)?;
13988 self.1.encode(encoder, offset + 8, depth)?;
13989 Ok(())
13990 }
13991 }
13992
13993 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13994 for BufferCollectionWaitForBuffersAllocatedResponse
13995 {
13996 #[inline(always)]
13997 fn new_empty() -> Self {
13998 Self {
13999 status: fidl::new_empty!(i32, fidl::encoding::DefaultFuchsiaResourceDialect),
14000 buffer_collection_info: fidl::new_empty!(
14001 BufferCollectionInfo2,
14002 fidl::encoding::DefaultFuchsiaResourceDialect
14003 ),
14004 }
14005 }
14006
14007 #[inline]
14008 unsafe fn decode(
14009 &mut self,
14010 decoder: &mut fidl::encoding::Decoder<
14011 '_,
14012 fidl::encoding::DefaultFuchsiaResourceDialect,
14013 >,
14014 offset: usize,
14015 _depth: fidl::encoding::Depth,
14016 ) -> fidl::Result<()> {
14017 decoder.debug_check_bounds::<Self>(offset);
14018 // Verify that padding bytes are zero.
14019 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
14020 let padval = unsafe { (ptr as *const u64).read_unaligned() };
14021 let mask = 0xffffffff00000000u64;
14022 let maskedval = padval & mask;
14023 if maskedval != 0 {
14024 return Err(fidl::Error::NonZeroPadding {
14025 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
14026 });
14027 }
14028 fidl::decode!(
14029 i32,
14030 fidl::encoding::DefaultFuchsiaResourceDialect,
14031 &mut self.status,
14032 decoder,
14033 offset + 0,
14034 _depth
14035 )?;
14036 fidl::decode!(
14037 BufferCollectionInfo2,
14038 fidl::encoding::DefaultFuchsiaResourceDialect,
14039 &mut self.buffer_collection_info,
14040 decoder,
14041 offset + 8,
14042 _depth
14043 )?;
14044 Ok(())
14045 }
14046 }
14047
14048 impl fidl::encoding::ResourceTypeMarker for NodeGetNodeRefResponse {
14049 type Borrowed<'a> = &'a mut Self;
14050 fn take_or_borrow<'a>(
14051 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14052 ) -> Self::Borrowed<'a> {
14053 value
14054 }
14055 }
14056
14057 unsafe impl fidl::encoding::TypeMarker for NodeGetNodeRefResponse {
14058 type Owned = Self;
14059
14060 #[inline(always)]
14061 fn inline_align(_context: fidl::encoding::Context) -> usize {
14062 4
14063 }
14064
14065 #[inline(always)]
14066 fn inline_size(_context: fidl::encoding::Context) -> usize {
14067 4
14068 }
14069 }
14070
14071 unsafe impl
14072 fidl::encoding::Encode<
14073 NodeGetNodeRefResponse,
14074 fidl::encoding::DefaultFuchsiaResourceDialect,
14075 > for &mut NodeGetNodeRefResponse
14076 {
14077 #[inline]
14078 unsafe fn encode(
14079 self,
14080 encoder: &mut fidl::encoding::Encoder<
14081 '_,
14082 fidl::encoding::DefaultFuchsiaResourceDialect,
14083 >,
14084 offset: usize,
14085 _depth: fidl::encoding::Depth,
14086 ) -> fidl::Result<()> {
14087 encoder.debug_check_bounds::<NodeGetNodeRefResponse>(offset);
14088 // Delegate to tuple encoding.
14089 fidl::encoding::Encode::<
14090 NodeGetNodeRefResponse,
14091 fidl::encoding::DefaultFuchsiaResourceDialect,
14092 >::encode(
14093 (<fidl::encoding::HandleType<
14094 fidl::Event,
14095 { fidl::ObjectType::EVENT.into_raw() },
14096 2147483648,
14097 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
14098 &mut self.node_ref
14099 ),),
14100 encoder,
14101 offset,
14102 _depth,
14103 )
14104 }
14105 }
14106 unsafe impl<
14107 T0: fidl::encoding::Encode<
14108 fidl::encoding::HandleType<
14109 fidl::Event,
14110 { fidl::ObjectType::EVENT.into_raw() },
14111 2147483648,
14112 >,
14113 fidl::encoding::DefaultFuchsiaResourceDialect,
14114 >,
14115 >
14116 fidl::encoding::Encode<
14117 NodeGetNodeRefResponse,
14118 fidl::encoding::DefaultFuchsiaResourceDialect,
14119 > for (T0,)
14120 {
14121 #[inline]
14122 unsafe fn encode(
14123 self,
14124 encoder: &mut fidl::encoding::Encoder<
14125 '_,
14126 fidl::encoding::DefaultFuchsiaResourceDialect,
14127 >,
14128 offset: usize,
14129 depth: fidl::encoding::Depth,
14130 ) -> fidl::Result<()> {
14131 encoder.debug_check_bounds::<NodeGetNodeRefResponse>(offset);
14132 // Zero out padding regions. There's no need to apply masks
14133 // because the unmasked parts will be overwritten by fields.
14134 // Write the fields.
14135 self.0.encode(encoder, offset + 0, depth)?;
14136 Ok(())
14137 }
14138 }
14139
14140 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14141 for NodeGetNodeRefResponse
14142 {
14143 #[inline(always)]
14144 fn new_empty() -> Self {
14145 Self {
14146 node_ref: fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
14147 }
14148 }
14149
14150 #[inline]
14151 unsafe fn decode(
14152 &mut self,
14153 decoder: &mut fidl::encoding::Decoder<
14154 '_,
14155 fidl::encoding::DefaultFuchsiaResourceDialect,
14156 >,
14157 offset: usize,
14158 _depth: fidl::encoding::Depth,
14159 ) -> fidl::Result<()> {
14160 decoder.debug_check_bounds::<Self>(offset);
14161 // Verify that padding bytes are zero.
14162 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.node_ref, decoder, offset + 0, _depth)?;
14163 Ok(())
14164 }
14165 }
14166
14167 impl fidl::encoding::ResourceTypeMarker for NodeIsAlternateForRequest {
14168 type Borrowed<'a> = &'a mut Self;
14169 fn take_or_borrow<'a>(
14170 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14171 ) -> Self::Borrowed<'a> {
14172 value
14173 }
14174 }
14175
14176 unsafe impl fidl::encoding::TypeMarker for NodeIsAlternateForRequest {
14177 type Owned = Self;
14178
14179 #[inline(always)]
14180 fn inline_align(_context: fidl::encoding::Context) -> usize {
14181 4
14182 }
14183
14184 #[inline(always)]
14185 fn inline_size(_context: fidl::encoding::Context) -> usize {
14186 4
14187 }
14188 }
14189
14190 unsafe impl
14191 fidl::encoding::Encode<
14192 NodeIsAlternateForRequest,
14193 fidl::encoding::DefaultFuchsiaResourceDialect,
14194 > for &mut NodeIsAlternateForRequest
14195 {
14196 #[inline]
14197 unsafe fn encode(
14198 self,
14199 encoder: &mut fidl::encoding::Encoder<
14200 '_,
14201 fidl::encoding::DefaultFuchsiaResourceDialect,
14202 >,
14203 offset: usize,
14204 _depth: fidl::encoding::Depth,
14205 ) -> fidl::Result<()> {
14206 encoder.debug_check_bounds::<NodeIsAlternateForRequest>(offset);
14207 // Delegate to tuple encoding.
14208 fidl::encoding::Encode::<
14209 NodeIsAlternateForRequest,
14210 fidl::encoding::DefaultFuchsiaResourceDialect,
14211 >::encode(
14212 (<fidl::encoding::HandleType<
14213 fidl::Event,
14214 { fidl::ObjectType::EVENT.into_raw() },
14215 2147483648,
14216 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
14217 &mut self.node_ref
14218 ),),
14219 encoder,
14220 offset,
14221 _depth,
14222 )
14223 }
14224 }
14225 unsafe impl<
14226 T0: fidl::encoding::Encode<
14227 fidl::encoding::HandleType<
14228 fidl::Event,
14229 { fidl::ObjectType::EVENT.into_raw() },
14230 2147483648,
14231 >,
14232 fidl::encoding::DefaultFuchsiaResourceDialect,
14233 >,
14234 >
14235 fidl::encoding::Encode<
14236 NodeIsAlternateForRequest,
14237 fidl::encoding::DefaultFuchsiaResourceDialect,
14238 > for (T0,)
14239 {
14240 #[inline]
14241 unsafe fn encode(
14242 self,
14243 encoder: &mut fidl::encoding::Encoder<
14244 '_,
14245 fidl::encoding::DefaultFuchsiaResourceDialect,
14246 >,
14247 offset: usize,
14248 depth: fidl::encoding::Depth,
14249 ) -> fidl::Result<()> {
14250 encoder.debug_check_bounds::<NodeIsAlternateForRequest>(offset);
14251 // Zero out padding regions. There's no need to apply masks
14252 // because the unmasked parts will be overwritten by fields.
14253 // Write the fields.
14254 self.0.encode(encoder, offset + 0, depth)?;
14255 Ok(())
14256 }
14257 }
14258
14259 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14260 for NodeIsAlternateForRequest
14261 {
14262 #[inline(always)]
14263 fn new_empty() -> Self {
14264 Self {
14265 node_ref: fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
14266 }
14267 }
14268
14269 #[inline]
14270 unsafe fn decode(
14271 &mut self,
14272 decoder: &mut fidl::encoding::Decoder<
14273 '_,
14274 fidl::encoding::DefaultFuchsiaResourceDialect,
14275 >,
14276 offset: usize,
14277 _depth: fidl::encoding::Depth,
14278 ) -> fidl::Result<()> {
14279 decoder.debug_check_bounds::<Self>(offset);
14280 // Verify that padding bytes are zero.
14281 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.node_ref, decoder, offset + 0, _depth)?;
14282 Ok(())
14283 }
14284 }
14285
14286 impl fidl::encoding::ResourceTypeMarker for SingleBufferInfo {
14287 type Borrowed<'a> = &'a mut Self;
14288 fn take_or_borrow<'a>(
14289 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14290 ) -> Self::Borrowed<'a> {
14291 value
14292 }
14293 }
14294
14295 unsafe impl fidl::encoding::TypeMarker for SingleBufferInfo {
14296 type Owned = Self;
14297
14298 #[inline(always)]
14299 fn inline_align(_context: fidl::encoding::Context) -> usize {
14300 8
14301 }
14302
14303 #[inline(always)]
14304 fn inline_size(_context: fidl::encoding::Context) -> usize {
14305 280
14306 }
14307 }
14308
14309 unsafe impl
14310 fidl::encoding::Encode<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
14311 for &mut SingleBufferInfo
14312 {
14313 #[inline]
14314 unsafe fn encode(
14315 self,
14316 encoder: &mut fidl::encoding::Encoder<
14317 '_,
14318 fidl::encoding::DefaultFuchsiaResourceDialect,
14319 >,
14320 offset: usize,
14321 _depth: fidl::encoding::Depth,
14322 ) -> fidl::Result<()> {
14323 encoder.debug_check_bounds::<SingleBufferInfo>(offset);
14324 // Delegate to tuple encoding.
14325 fidl::encoding::Encode::<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
14326 (
14327 <SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow(&self.settings),
14328 <VmoBuffer as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffer),
14329 ),
14330 encoder, offset, _depth
14331 )
14332 }
14333 }
14334 unsafe impl<
14335 T0: fidl::encoding::Encode<
14336 SingleBufferSettings,
14337 fidl::encoding::DefaultFuchsiaResourceDialect,
14338 >,
14339 T1: fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>,
14340 >
14341 fidl::encoding::Encode<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
14342 for (T0, T1)
14343 {
14344 #[inline]
14345 unsafe fn encode(
14346 self,
14347 encoder: &mut fidl::encoding::Encoder<
14348 '_,
14349 fidl::encoding::DefaultFuchsiaResourceDialect,
14350 >,
14351 offset: usize,
14352 depth: fidl::encoding::Depth,
14353 ) -> fidl::Result<()> {
14354 encoder.debug_check_bounds::<SingleBufferInfo>(offset);
14355 // Zero out padding regions. There's no need to apply masks
14356 // because the unmasked parts will be overwritten by fields.
14357 // Write the fields.
14358 self.0.encode(encoder, offset + 0, depth)?;
14359 self.1.encode(encoder, offset + 264, depth)?;
14360 Ok(())
14361 }
14362 }
14363
14364 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14365 for SingleBufferInfo
14366 {
14367 #[inline(always)]
14368 fn new_empty() -> Self {
14369 Self {
14370 settings: fidl::new_empty!(
14371 SingleBufferSettings,
14372 fidl::encoding::DefaultFuchsiaResourceDialect
14373 ),
14374 buffer: fidl::new_empty!(VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect),
14375 }
14376 }
14377
14378 #[inline]
14379 unsafe fn decode(
14380 &mut self,
14381 decoder: &mut fidl::encoding::Decoder<
14382 '_,
14383 fidl::encoding::DefaultFuchsiaResourceDialect,
14384 >,
14385 offset: usize,
14386 _depth: fidl::encoding::Depth,
14387 ) -> fidl::Result<()> {
14388 decoder.debug_check_bounds::<Self>(offset);
14389 // Verify that padding bytes are zero.
14390 fidl::decode!(
14391 SingleBufferSettings,
14392 fidl::encoding::DefaultFuchsiaResourceDialect,
14393 &mut self.settings,
14394 decoder,
14395 offset + 0,
14396 _depth
14397 )?;
14398 fidl::decode!(
14399 VmoBuffer,
14400 fidl::encoding::DefaultFuchsiaResourceDialect,
14401 &mut self.buffer,
14402 decoder,
14403 offset + 264,
14404 _depth
14405 )?;
14406 Ok(())
14407 }
14408 }
14409
14410 impl fidl::encoding::ResourceTypeMarker for VmoBuffer {
14411 type Borrowed<'a> = &'a mut Self;
14412 fn take_or_borrow<'a>(
14413 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14414 ) -> Self::Borrowed<'a> {
14415 value
14416 }
14417 }
14418
14419 unsafe impl fidl::encoding::TypeMarker for VmoBuffer {
14420 type Owned = Self;
14421
14422 #[inline(always)]
14423 fn inline_align(_context: fidl::encoding::Context) -> usize {
14424 8
14425 }
14426
14427 #[inline(always)]
14428 fn inline_size(_context: fidl::encoding::Context) -> usize {
14429 16
14430 }
14431 }
14432
14433 unsafe impl fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>
14434 for &mut VmoBuffer
14435 {
14436 #[inline]
14437 unsafe fn encode(
14438 self,
14439 encoder: &mut fidl::encoding::Encoder<
14440 '_,
14441 fidl::encoding::DefaultFuchsiaResourceDialect,
14442 >,
14443 offset: usize,
14444 _depth: fidl::encoding::Depth,
14445 ) -> fidl::Result<()> {
14446 encoder.debug_check_bounds::<VmoBuffer>(offset);
14447 // Delegate to tuple encoding.
14448 fidl::encoding::Encode::<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
14449 (
14450 <fidl::encoding::Optional<fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.vmo),
14451 <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.vmo_usable_start),
14452 ),
14453 encoder, offset, _depth
14454 )
14455 }
14456 }
14457 unsafe impl<
14458 T0: fidl::encoding::Encode<
14459 fidl::encoding::Optional<
14460 fidl::encoding::HandleType<
14461 fidl::Vmo,
14462 { fidl::ObjectType::VMO.into_raw() },
14463 2147483648,
14464 >,
14465 >,
14466 fidl::encoding::DefaultFuchsiaResourceDialect,
14467 >,
14468 T1: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
14469 > fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>
14470 for (T0, T1)
14471 {
14472 #[inline]
14473 unsafe fn encode(
14474 self,
14475 encoder: &mut fidl::encoding::Encoder<
14476 '_,
14477 fidl::encoding::DefaultFuchsiaResourceDialect,
14478 >,
14479 offset: usize,
14480 depth: fidl::encoding::Depth,
14481 ) -> fidl::Result<()> {
14482 encoder.debug_check_bounds::<VmoBuffer>(offset);
14483 // Zero out padding regions. There's no need to apply masks
14484 // because the unmasked parts will be overwritten by fields.
14485 unsafe {
14486 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
14487 (ptr as *mut u64).write_unaligned(0);
14488 }
14489 // Write the fields.
14490 self.0.encode(encoder, offset + 0, depth)?;
14491 self.1.encode(encoder, offset + 8, depth)?;
14492 Ok(())
14493 }
14494 }
14495
14496 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect> for VmoBuffer {
14497 #[inline(always)]
14498 fn new_empty() -> Self {
14499 Self {
14500 vmo: fidl::new_empty!(
14501 fidl::encoding::Optional<
14502 fidl::encoding::HandleType<
14503 fidl::Vmo,
14504 { fidl::ObjectType::VMO.into_raw() },
14505 2147483648,
14506 >,
14507 >,
14508 fidl::encoding::DefaultFuchsiaResourceDialect
14509 ),
14510 vmo_usable_start: fidl::new_empty!(
14511 u64,
14512 fidl::encoding::DefaultFuchsiaResourceDialect
14513 ),
14514 }
14515 }
14516
14517 #[inline]
14518 unsafe fn decode(
14519 &mut self,
14520 decoder: &mut fidl::encoding::Decoder<
14521 '_,
14522 fidl::encoding::DefaultFuchsiaResourceDialect,
14523 >,
14524 offset: usize,
14525 _depth: fidl::encoding::Depth,
14526 ) -> fidl::Result<()> {
14527 decoder.debug_check_bounds::<Self>(offset);
14528 // Verify that padding bytes are zero.
14529 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
14530 let padval = unsafe { (ptr as *const u64).read_unaligned() };
14531 let mask = 0xffffffff00000000u64;
14532 let maskedval = padval & mask;
14533 if maskedval != 0 {
14534 return Err(fidl::Error::NonZeroPadding {
14535 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
14536 });
14537 }
14538 fidl::decode!(
14539 fidl::encoding::Optional<
14540 fidl::encoding::HandleType<
14541 fidl::Vmo,
14542 { fidl::ObjectType::VMO.into_raw() },
14543 2147483648,
14544 >,
14545 >,
14546 fidl::encoding::DefaultFuchsiaResourceDialect,
14547 &mut self.vmo,
14548 decoder,
14549 offset + 0,
14550 _depth
14551 )?;
14552 fidl::decode!(
14553 u64,
14554 fidl::encoding::DefaultFuchsiaResourceDialect,
14555 &mut self.vmo_usable_start,
14556 decoder,
14557 offset + 8,
14558 _depth
14559 )?;
14560 Ok(())
14561 }
14562 }
14563
14564 impl BufferCollectionTokenGroupCreateChildRequest {
14565 #[inline(always)]
14566 fn max_ordinal_present(&self) -> u64 {
14567 if let Some(_) = self.rights_attenuation_mask {
14568 return 2;
14569 }
14570 if let Some(_) = self.token_request {
14571 return 1;
14572 }
14573 0
14574 }
14575 }
14576
14577 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildRequest {
14578 type Borrowed<'a> = &'a mut Self;
14579 fn take_or_borrow<'a>(
14580 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14581 ) -> Self::Borrowed<'a> {
14582 value
14583 }
14584 }
14585
14586 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildRequest {
14587 type Owned = Self;
14588
14589 #[inline(always)]
14590 fn inline_align(_context: fidl::encoding::Context) -> usize {
14591 8
14592 }
14593
14594 #[inline(always)]
14595 fn inline_size(_context: fidl::encoding::Context) -> usize {
14596 16
14597 }
14598 }
14599
14600 unsafe impl
14601 fidl::encoding::Encode<
14602 BufferCollectionTokenGroupCreateChildRequest,
14603 fidl::encoding::DefaultFuchsiaResourceDialect,
14604 > for &mut BufferCollectionTokenGroupCreateChildRequest
14605 {
14606 unsafe fn encode(
14607 self,
14608 encoder: &mut fidl::encoding::Encoder<
14609 '_,
14610 fidl::encoding::DefaultFuchsiaResourceDialect,
14611 >,
14612 offset: usize,
14613 mut depth: fidl::encoding::Depth,
14614 ) -> fidl::Result<()> {
14615 encoder.debug_check_bounds::<BufferCollectionTokenGroupCreateChildRequest>(offset);
14616 // Vector header
14617 let max_ordinal: u64 = self.max_ordinal_present();
14618 encoder.write_num(max_ordinal, offset);
14619 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
14620 // Calling encoder.out_of_line_offset(0) is not allowed.
14621 if max_ordinal == 0 {
14622 return Ok(());
14623 }
14624 depth.increment()?;
14625 let envelope_size = 8;
14626 let bytes_len = max_ordinal as usize * envelope_size;
14627 #[allow(unused_variables)]
14628 let offset = encoder.out_of_line_offset(bytes_len);
14629 let mut _prev_end_offset: usize = 0;
14630 if 1 > max_ordinal {
14631 return Ok(());
14632 }
14633
14634 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
14635 // are envelope_size bytes.
14636 let cur_offset: usize = (1 - 1) * envelope_size;
14637
14638 // Zero reserved fields.
14639 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
14640
14641 // Safety:
14642 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
14643 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
14644 // envelope_size bytes, there is always sufficient room.
14645 fidl::encoding::encode_in_envelope_optional::<
14646 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
14647 fidl::encoding::DefaultFuchsiaResourceDialect,
14648 >(
14649 self.token_request.as_mut().map(
14650 <fidl::encoding::Endpoint<
14651 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14652 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
14653 ),
14654 encoder,
14655 offset + cur_offset,
14656 depth,
14657 )?;
14658
14659 _prev_end_offset = cur_offset + envelope_size;
14660 if 2 > max_ordinal {
14661 return Ok(());
14662 }
14663
14664 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
14665 // are envelope_size bytes.
14666 let cur_offset: usize = (2 - 1) * envelope_size;
14667
14668 // Zero reserved fields.
14669 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
14670
14671 // Safety:
14672 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
14673 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
14674 // envelope_size bytes, there is always sufficient room.
14675 fidl::encoding::encode_in_envelope_optional::<
14676 u32,
14677 fidl::encoding::DefaultFuchsiaResourceDialect,
14678 >(
14679 self.rights_attenuation_mask
14680 .as_ref()
14681 .map(<u32 as fidl::encoding::ValueTypeMarker>::borrow),
14682 encoder,
14683 offset + cur_offset,
14684 depth,
14685 )?;
14686
14687 _prev_end_offset = cur_offset + envelope_size;
14688
14689 Ok(())
14690 }
14691 }
14692
14693 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14694 for BufferCollectionTokenGroupCreateChildRequest
14695 {
14696 #[inline(always)]
14697 fn new_empty() -> Self {
14698 Self::default()
14699 }
14700
14701 unsafe fn decode(
14702 &mut self,
14703 decoder: &mut fidl::encoding::Decoder<
14704 '_,
14705 fidl::encoding::DefaultFuchsiaResourceDialect,
14706 >,
14707 offset: usize,
14708 mut depth: fidl::encoding::Depth,
14709 ) -> fidl::Result<()> {
14710 decoder.debug_check_bounds::<Self>(offset);
14711 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
14712 None => return Err(fidl::Error::NotNullable),
14713 Some(len) => len,
14714 };
14715 // Calling decoder.out_of_line_offset(0) is not allowed.
14716 if len == 0 {
14717 return Ok(());
14718 };
14719 depth.increment()?;
14720 let envelope_size = 8;
14721 let bytes_len = len * envelope_size;
14722 let offset = decoder.out_of_line_offset(bytes_len)?;
14723 // Decode the envelope for each type.
14724 let mut _next_ordinal_to_read = 0;
14725 let mut next_offset = offset;
14726 let end_offset = offset + bytes_len;
14727 _next_ordinal_to_read += 1;
14728 if next_offset >= end_offset {
14729 return Ok(());
14730 }
14731
14732 // Decode unknown envelopes for gaps in ordinals.
14733 while _next_ordinal_to_read < 1 {
14734 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14735 _next_ordinal_to_read += 1;
14736 next_offset += envelope_size;
14737 }
14738
14739 let next_out_of_line = decoder.next_out_of_line();
14740 let handles_before = decoder.remaining_handles();
14741 if let Some((inlined, num_bytes, num_handles)) =
14742 fidl::encoding::decode_envelope_header(decoder, next_offset)?
14743 {
14744 let member_inline_size = <fidl::encoding::Endpoint<
14745 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14746 > as fidl::encoding::TypeMarker>::inline_size(
14747 decoder.context
14748 );
14749 if inlined != (member_inline_size <= 4) {
14750 return Err(fidl::Error::InvalidInlineBitInEnvelope);
14751 }
14752 let inner_offset;
14753 let mut inner_depth = depth.clone();
14754 if inlined {
14755 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
14756 inner_offset = next_offset;
14757 } else {
14758 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
14759 inner_depth.increment()?;
14760 }
14761 let val_ref = self.token_request.get_or_insert_with(|| {
14762 fidl::new_empty!(
14763 fidl::encoding::Endpoint<
14764 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14765 >,
14766 fidl::encoding::DefaultFuchsiaResourceDialect
14767 )
14768 });
14769 fidl::decode!(
14770 fidl::encoding::Endpoint<
14771 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14772 >,
14773 fidl::encoding::DefaultFuchsiaResourceDialect,
14774 val_ref,
14775 decoder,
14776 inner_offset,
14777 inner_depth
14778 )?;
14779 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
14780 {
14781 return Err(fidl::Error::InvalidNumBytesInEnvelope);
14782 }
14783 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
14784 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
14785 }
14786 }
14787
14788 next_offset += envelope_size;
14789 _next_ordinal_to_read += 1;
14790 if next_offset >= end_offset {
14791 return Ok(());
14792 }
14793
14794 // Decode unknown envelopes for gaps in ordinals.
14795 while _next_ordinal_to_read < 2 {
14796 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14797 _next_ordinal_to_read += 1;
14798 next_offset += envelope_size;
14799 }
14800
14801 let next_out_of_line = decoder.next_out_of_line();
14802 let handles_before = decoder.remaining_handles();
14803 if let Some((inlined, num_bytes, num_handles)) =
14804 fidl::encoding::decode_envelope_header(decoder, next_offset)?
14805 {
14806 let member_inline_size =
14807 <u32 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
14808 if inlined != (member_inline_size <= 4) {
14809 return Err(fidl::Error::InvalidInlineBitInEnvelope);
14810 }
14811 let inner_offset;
14812 let mut inner_depth = depth.clone();
14813 if inlined {
14814 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
14815 inner_offset = next_offset;
14816 } else {
14817 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
14818 inner_depth.increment()?;
14819 }
14820 let val_ref = self.rights_attenuation_mask.get_or_insert_with(|| {
14821 fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect)
14822 });
14823 fidl::decode!(
14824 u32,
14825 fidl::encoding::DefaultFuchsiaResourceDialect,
14826 val_ref,
14827 decoder,
14828 inner_offset,
14829 inner_depth
14830 )?;
14831 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
14832 {
14833 return Err(fidl::Error::InvalidNumBytesInEnvelope);
14834 }
14835 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
14836 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
14837 }
14838 }
14839
14840 next_offset += envelope_size;
14841
14842 // Decode the remaining unknown envelopes.
14843 while next_offset < end_offset {
14844 _next_ordinal_to_read += 1;
14845 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14846 next_offset += envelope_size;
14847 }
14848
14849 Ok(())
14850 }
14851 }
14852}