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/// Deprecated. Use ['fuchsia.sysmem2.BufferCollectionInfo'].
78///
79/// This type is deprecated for new code but still used by some camera code.
80#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
81pub struct BufferCollectionInfo {
82 /// The number of buffers in the collection.
83 pub buffer_count: u32,
84 /// Describes how the contents of buffers are represented.
85 /// All buffers within the collection have the same format.
86 pub format: BufferFormat,
87 /// VMO handles for each buffer in the collection.
88 /// The VMOs are only present when the buffers are backed by VMOs.
89 ///
90 /// If present, all the VMOs after `buffer_count` are invalid handles.
91 /// All buffer VMO handles have identical size and access rights.
92 /// The VMO access rights are determined based on the usages which the
93 /// client specified when allocating the buffer collection. For example,
94 /// a client which expressed a read-only usage will receive VMOs without
95 /// write rights.
96 pub vmos: [Option<fidl::Vmo>; 64],
97 /// The size of each VMO provided.
98 /// This property is only present when the buffers are backed by VMOs.
99 pub vmo_size: u64,
100}
101
102impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for BufferCollectionInfo {}
103
104/// Information about a buffer collection and its buffers.
105#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
106pub struct BufferCollectionInfo2 {
107 /// The total number of buffers.
108 pub buffer_count: u32,
109 /// These settings apply to all the buffers in the initial buffer allocation.
110 pub settings: SingleBufferSettings,
111 /// VMO handles (and vmo_usable_start offset) for each buffer in the
112 /// collection.
113 ///
114 /// If present, all the VMOs at or after index `buffer_count` are invalid
115 /// (0) handles.
116 ///
117 /// All buffer VMO handles have identical size and access rights. The size
118 /// is in settings.buffer_settings.size_bytes.
119 ///
120 /// The VMO access rights are determined based on the usages which the
121 /// client specified when allocating the buffer collection. For example,
122 /// a client which expressed a read-only usage will receive VMOs without
123 /// write rights. In addition, the rights can be attenuated by the
124 /// parameter to BufferCollectionToken.Duplicate() calls.
125 pub buffers: [VmoBuffer; 64],
126}
127
128impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for BufferCollectionInfo2 {}
129
130#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
131pub struct BufferCollectionTokenCreateBufferCollectionTokenGroupRequest {
132 pub group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
133}
134
135impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
136 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
137{
138}
139
140#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
141pub struct BufferCollectionTokenDuplicateRequest {
142 pub rights_attenuation_mask: u32,
143 pub token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
144}
145
146impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
147 for BufferCollectionTokenDuplicateRequest
148{
149}
150
151#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
152pub struct BufferCollectionTokenDuplicateSyncResponse {
153 pub tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
154}
155
156impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
157 for BufferCollectionTokenDuplicateSyncResponse
158{
159}
160
161#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
162pub struct BufferCollectionTokenGroupCreateChildrenSyncResponse {
163 pub tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
164}
165
166impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
167 for BufferCollectionTokenGroupCreateChildrenSyncResponse
168{
169}
170
171#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
172pub struct BufferCollectionWaitForBuffersAllocatedResponse {
173 pub status: i32,
174 pub buffer_collection_info: BufferCollectionInfo2,
175}
176
177impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
178 for BufferCollectionWaitForBuffersAllocatedResponse
179{
180}
181
182#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
183pub struct NodeGetNodeRefResponse {
184 pub node_ref: fidl::Event,
185}
186
187impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for NodeGetNodeRefResponse {}
188
189#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
190pub struct NodeIsAlternateForRequest {
191 pub node_ref: fidl::Event,
192}
193
194impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for NodeIsAlternateForRequest {}
195
196/// There is no current replacement for this type, but if your use case needs
197/// incremental buffer allocation within a single collection, please reach out.
198#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
199pub struct SingleBufferInfo {
200 pub settings: SingleBufferSettings,
201 pub buffer: VmoBuffer,
202}
203
204impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for SingleBufferInfo {}
205
206#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
207pub struct VmoBuffer {
208 /// The same VMO can be used by more than one CodecBuffer (only of the same
209 /// buffer_lifetime_ordinal), but each vmo handle must be a separate handle.
210 ///
211 /// The vmo field can be 0 if this is a VmoBuffer in BufferCollectionInfo_2
212 /// that's at or beyond BufferCollectionInfo_2.buffer_count.
213 pub vmo: Option<fidl::Vmo>,
214 /// Offset within the VMO of the first usable byte. Must be < the VMO's
215 /// size in bytes, and leave sufficient room for
216 /// BufferMemorySettings.size_bytes before the end of the VMO.
217 pub vmo_usable_start: u64,
218}
219
220impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for VmoBuffer {}
221
222#[derive(Debug, Default, PartialEq)]
223pub struct BufferCollectionTokenGroupCreateChildRequest {
224 /// Must be set.
225 pub token_request: Option<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
226 /// If not set, the default is ZX_RIGHT_SAME_RIGHTS.
227 pub rights_attenuation_mask: Option<u32>,
228 #[doc(hidden)]
229 pub __source_breaking: fidl::marker::SourceBreaking,
230}
231
232impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
233 for BufferCollectionTokenGroupCreateChildRequest
234{
235}
236
237#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
238pub struct AllocatorMarker;
239
240impl fidl::endpoints::ProtocolMarker for AllocatorMarker {
241 type Proxy = AllocatorProxy;
242 type RequestStream = AllocatorRequestStream;
243 #[cfg(target_os = "fuchsia")]
244 type SynchronousProxy = AllocatorSynchronousProxy;
245
246 const DEBUG_NAME: &'static str = "fuchsia.sysmem.Allocator";
247}
248impl fidl::endpoints::DiscoverableProtocolMarker for AllocatorMarker {}
249
250pub trait AllocatorProxyInterface: Send + Sync {
251 fn r#allocate_non_shared_collection(
252 &self,
253 collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
254 ) -> Result<(), fidl::Error>;
255 fn r#allocate_shared_collection(
256 &self,
257 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
258 ) -> Result<(), fidl::Error>;
259 fn r#bind_shared_collection(
260 &self,
261 token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
262 buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
263 ) -> Result<(), fidl::Error>;
264 type ValidateBufferCollectionTokenResponseFut: std::future::Future<Output = Result<bool, fidl::Error>>
265 + Send;
266 fn r#validate_buffer_collection_token(
267 &self,
268 token_server_koid: u64,
269 ) -> Self::ValidateBufferCollectionTokenResponseFut;
270 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
271 fn r#connect_to_sysmem2_allocator(
272 &self,
273 allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
274 ) -> Result<(), fidl::Error>;
275}
276#[derive(Debug)]
277#[cfg(target_os = "fuchsia")]
278pub struct AllocatorSynchronousProxy {
279 client: fidl::client::sync::Client,
280}
281
282#[cfg(target_os = "fuchsia")]
283impl fidl::endpoints::SynchronousProxy for AllocatorSynchronousProxy {
284 type Proxy = AllocatorProxy;
285 type Protocol = AllocatorMarker;
286
287 fn from_channel(inner: fidl::Channel) -> Self {
288 Self::new(inner)
289 }
290
291 fn into_channel(self) -> fidl::Channel {
292 self.client.into_channel()
293 }
294
295 fn as_channel(&self) -> &fidl::Channel {
296 self.client.as_channel()
297 }
298}
299
300#[cfg(target_os = "fuchsia")]
301impl AllocatorSynchronousProxy {
302 pub fn new(channel: fidl::Channel) -> Self {
303 let protocol_name = <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
304 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
305 }
306
307 pub fn into_channel(self) -> fidl::Channel {
308 self.client.into_channel()
309 }
310
311 /// Waits until an event arrives and returns it. It is safe for other
312 /// threads to make concurrent requests while waiting for an event.
313 pub fn wait_for_event(
314 &self,
315 deadline: zx::MonotonicInstant,
316 ) -> Result<AllocatorEvent, fidl::Error> {
317 AllocatorEvent::decode(self.client.wait_for_event(deadline)?)
318 }
319
320 /// Allocates a BufferCollection on behalf of a single client (aka initiator)
321 /// who is also the only participant (from the point of view of sysmem).
322 ///
323 /// This call exists mainly for temp/testing purposes. This call skips the
324 /// BufferCollectionToken stage, so there's no way to allow another
325 /// participant to specify its constraints.
326 ///
327 /// Real clients are encouraged to use AllocateSharedCollection() instead,
328 /// and to let relevant participants directly convey their own constraints to
329 /// sysmem.
330 ///
331 /// `collection_request` is the server end of the BufferCollection FIDL
332 /// channel. The client can call SetConstraints() and then
333 /// WaitForBuffersAllocated() on the client end of this channel to specify
334 /// constraints and then determine success/failure and get the
335 /// BufferCollectionInfo_2 for the BufferCollection. The client should also
336 /// keep the client end of this channel open while using the
337 /// BufferCollection, and should notice when this channel closes and stop
338 /// using the BufferCollection ASAP.
339 pub fn r#allocate_non_shared_collection(
340 &self,
341 mut collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
342 ) -> Result<(), fidl::Error> {
343 self.client.send::<AllocatorAllocateNonSharedCollectionRequest>(
344 (collection_request,),
345 0x20f79299bbb4d2c6,
346 fidl::encoding::DynamicFlags::empty(),
347 )
348 }
349
350 /// Creates a logical BufferCollectionToken which can be shared among
351 /// participants (using BufferCollectionToken.Duplicate()), and then
352 /// converted into a BufferCollection using BindSharedCollection().
353 ///
354 /// Success/failure to populate the BufferCollection with buffers is
355 /// determined via the BufferCollection interface.
356 pub fn r#allocate_shared_collection(
357 &self,
358 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
359 ) -> Result<(), fidl::Error> {
360 self.client.send::<AllocatorAllocateSharedCollectionRequest>(
361 (token_request,),
362 0x7a757a57bfda0f71,
363 fidl::encoding::DynamicFlags::empty(),
364 )
365 }
366
367 /// Convert a BufferCollectionToken into a connection to the logical
368 /// BufferCollection. The BufferCollection hasn't yet been populated with
369 /// buffers - the participant must first also send SetConstraints() via the
370 /// client end of buffer_collection.
371 ///
372 /// All BufferCollectionToken(s) duplicated from a logical
373 /// BufferCollectionToken created via AllocateSharedCollection() must be
374 /// turned in via BindSharedCollection() before the logical BufferCollection
375 /// will be populated with buffers.
376 ///
377 /// `token` the client endpoint of a channel whose server end was sent to
378 /// sysmem using AllocateSharedCollection or whose server end was sent to
379 /// sysmem using BufferCollectionToken.Duplicate(). The token is being
380 /// "exchanged" for a channel to the logical BufferCollection.
381 ///
382 /// `buffer_collection_request` the server end of a BufferCollection
383 /// channel. The sender retains the client end as usual. The
384 /// BufferCollection channel is a single participant's connection to the
385 /// logical BufferCollection. There typically will be other participants
386 /// with their own BufferCollection channel to the logical BufferCollection.
387 pub fn r#bind_shared_collection(
388 &self,
389 mut token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
390 mut buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
391 ) -> Result<(), fidl::Error> {
392 self.client.send::<AllocatorBindSharedCollectionRequest>(
393 (token, buffer_collection_request),
394 0x146eca7ec46ff4ee,
395 fidl::encoding::DynamicFlags::empty(),
396 )
397 }
398
399 /// Validate that a BufferCollectionToken is known to the sysmem server.
400 ///
401 /// This can be used in cases where BindSharedCollection() won't be called
402 /// until after BufferCollectionToken.Duplicate() +
403 /// BufferCollectionToken.Sync(), when the client code wants to know earlier
404 /// whether an incoming token is valid (so far).
405 ///
406 /// Calling BufferCollectionToken.Sync() on a token that isn't known to
407 /// sysmem risks the Sync() hanging forever.
408 ///
409 /// Given that an incoming token can become invalid at any time if any
410 /// participant drops their BufferCollectionToken(s) or BufferCollection(s),
411 /// authors of client code are encouraged to consider not calling
412 /// ValidateBufferCollectionToken() and instead dealing with async failure
413 /// of the BufferCollection.Sync() after all the
414 /// BufferCollectionToken.Duplicate() and BindSharedCollection() (before
415 /// sending any duplicate tokens to other processes).
416 ///
417 /// Regardless of the result of this call, this call has no effect on the
418 /// token with the referenced koid.
419 ///
420 /// A true result from this call doesn't guarantee that the token remains
421 /// valid for any duration afterwards.
422 ///
423 /// Client code will zx_object_get_info() on the client's token handle,
424 /// passing ZX_INFO_HANDLE_BASIC and getting back the related_koid
425 /// which then gets passed to ValidateBufferCollectionToken().
426 ///
427 /// If ValidateBufferCollectionToken() returns true, the token was known at
428 /// the time the sysmem server processed the call, but may no longer be
429 /// valid/known by the time the client code receives the response.
430 ///
431 /// If ValidateBufferCollectionToken() returns false, the token wasn't known
432 /// at the time the sysmem server processed the call, but the token may
433 /// become known by the time the client code receives the response. However
434 /// client code is not required to mitigate the possibility that the token
435 /// may become known late, since the source of the token should have synced
436 /// the token to sysmem before sending the token to the client code.
437 ///
438 /// If calling ValidateBufferCollectionToken() fails in some way, there will
439 /// be a zx_status_t from the FIDL layer.
440 ///
441 /// `token_server_koid` the koid of the server end of a channel that might
442 /// be a BufferCollectionToken channel. This can be obtained from
443 /// zx_object_get_info() ZX_INFO_HANDLE_BASIC related_koid.
444 pub fn r#validate_buffer_collection_token(
445 &self,
446 mut token_server_koid: u64,
447 ___deadline: zx::MonotonicInstant,
448 ) -> Result<bool, fidl::Error> {
449 let _response = self.client.send_query::<
450 AllocatorValidateBufferCollectionTokenRequest,
451 AllocatorValidateBufferCollectionTokenResponse,
452 >(
453 (token_server_koid,),
454 0x575b279b0236faea,
455 fidl::encoding::DynamicFlags::empty(),
456 ___deadline,
457 )?;
458 Ok(_response.is_known)
459 }
460
461 /// Set information about the current client that can be used by sysmem to
462 /// help debug leaking memory and hangs waiting for constraints. |name| can
463 /// be an arbitrary string, but the current process name (see
464 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
465 /// arbitrary id, but the current process ID (see
466 /// fsl::GetCurrentProcessKoid()) is a good default.
467 ///
468 /// This information is propagated to all BufferCollections created using
469 /// BindSharedCollection() or AllocateNonSharedCollection() from this
470 /// allocator. It does not affect BufferCollectionTokens, since they are
471 /// often passed cross-process and should have their names managed manually.
472 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
473 self.client.send::<AllocatorSetDebugClientInfoRequest>(
474 (name, id),
475 0x419f0d5b30728b26,
476 fidl::encoding::DynamicFlags::empty(),
477 )
478 }
479
480 /// This allows creating a sysmem2 `Allocator` given a sysmem(1)
481 /// `Allocator`.
482 ///
483 /// This is mainly useful in situations where library code is handed a
484 /// sysmem(1) allocator, but the library code has been updated to use
485 /// sysmem2. Typically the library will provide a way to pass in a sysmem2
486 /// `Allocator` instead, but client code isn't always in the same repo, so
487 /// this message allows the library to still accept the sysmem(1) Allocator
488 /// temporarily.
489 ///
490 /// The info set via `SetDebugClientInfo` (if any) is copied to the sysmem2
491 /// `Allocator`.
492 pub fn r#connect_to_sysmem2_allocator(
493 &self,
494 mut allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
495 ) -> Result<(), fidl::Error> {
496 self.client.send::<AllocatorConnectToSysmem2AllocatorRequest>(
497 (allocator_request,),
498 0x13db3e3abac2e24,
499 fidl::encoding::DynamicFlags::empty(),
500 )
501 }
502}
503
504#[cfg(target_os = "fuchsia")]
505impl From<AllocatorSynchronousProxy> for zx::Handle {
506 fn from(value: AllocatorSynchronousProxy) -> Self {
507 value.into_channel().into()
508 }
509}
510
511#[cfg(target_os = "fuchsia")]
512impl From<fidl::Channel> for AllocatorSynchronousProxy {
513 fn from(value: fidl::Channel) -> Self {
514 Self::new(value)
515 }
516}
517
518#[cfg(target_os = "fuchsia")]
519impl fidl::endpoints::FromClient for AllocatorSynchronousProxy {
520 type Protocol = AllocatorMarker;
521
522 fn from_client(value: fidl::endpoints::ClientEnd<AllocatorMarker>) -> Self {
523 Self::new(value.into_channel())
524 }
525}
526
527#[derive(Debug, Clone)]
528pub struct AllocatorProxy {
529 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
530}
531
532impl fidl::endpoints::Proxy for AllocatorProxy {
533 type Protocol = AllocatorMarker;
534
535 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
536 Self::new(inner)
537 }
538
539 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
540 self.client.into_channel().map_err(|client| Self { client })
541 }
542
543 fn as_channel(&self) -> &::fidl::AsyncChannel {
544 self.client.as_channel()
545 }
546}
547
548impl AllocatorProxy {
549 /// Create a new Proxy for fuchsia.sysmem/Allocator.
550 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
551 let protocol_name = <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
552 Self { client: fidl::client::Client::new(channel, protocol_name) }
553 }
554
555 /// Get a Stream of events from the remote end of the protocol.
556 ///
557 /// # Panics
558 ///
559 /// Panics if the event stream was already taken.
560 pub fn take_event_stream(&self) -> AllocatorEventStream {
561 AllocatorEventStream { event_receiver: self.client.take_event_receiver() }
562 }
563
564 /// Allocates a BufferCollection on behalf of a single client (aka initiator)
565 /// who is also the only participant (from the point of view of sysmem).
566 ///
567 /// This call exists mainly for temp/testing purposes. This call skips the
568 /// BufferCollectionToken stage, so there's no way to allow another
569 /// participant to specify its constraints.
570 ///
571 /// Real clients are encouraged to use AllocateSharedCollection() instead,
572 /// and to let relevant participants directly convey their own constraints to
573 /// sysmem.
574 ///
575 /// `collection_request` is the server end of the BufferCollection FIDL
576 /// channel. The client can call SetConstraints() and then
577 /// WaitForBuffersAllocated() on the client end of this channel to specify
578 /// constraints and then determine success/failure and get the
579 /// BufferCollectionInfo_2 for the BufferCollection. The client should also
580 /// keep the client end of this channel open while using the
581 /// BufferCollection, and should notice when this channel closes and stop
582 /// using the BufferCollection ASAP.
583 pub fn r#allocate_non_shared_collection(
584 &self,
585 mut collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
586 ) -> Result<(), fidl::Error> {
587 AllocatorProxyInterface::r#allocate_non_shared_collection(self, collection_request)
588 }
589
590 /// Creates a logical BufferCollectionToken which can be shared among
591 /// participants (using BufferCollectionToken.Duplicate()), and then
592 /// converted into a BufferCollection using BindSharedCollection().
593 ///
594 /// Success/failure to populate the BufferCollection with buffers is
595 /// determined via the BufferCollection interface.
596 pub fn r#allocate_shared_collection(
597 &self,
598 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
599 ) -> Result<(), fidl::Error> {
600 AllocatorProxyInterface::r#allocate_shared_collection(self, token_request)
601 }
602
603 /// Convert a BufferCollectionToken into a connection to the logical
604 /// BufferCollection. The BufferCollection hasn't yet been populated with
605 /// buffers - the participant must first also send SetConstraints() via the
606 /// client end of buffer_collection.
607 ///
608 /// All BufferCollectionToken(s) duplicated from a logical
609 /// BufferCollectionToken created via AllocateSharedCollection() must be
610 /// turned in via BindSharedCollection() before the logical BufferCollection
611 /// will be populated with buffers.
612 ///
613 /// `token` the client endpoint of a channel whose server end was sent to
614 /// sysmem using AllocateSharedCollection or whose server end was sent to
615 /// sysmem using BufferCollectionToken.Duplicate(). The token is being
616 /// "exchanged" for a channel to the logical BufferCollection.
617 ///
618 /// `buffer_collection_request` the server end of a BufferCollection
619 /// channel. The sender retains the client end as usual. The
620 /// BufferCollection channel is a single participant's connection to the
621 /// logical BufferCollection. There typically will be other participants
622 /// with their own BufferCollection channel to the logical BufferCollection.
623 pub fn r#bind_shared_collection(
624 &self,
625 mut token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
626 mut buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
627 ) -> Result<(), fidl::Error> {
628 AllocatorProxyInterface::r#bind_shared_collection(self, token, buffer_collection_request)
629 }
630
631 /// Validate that a BufferCollectionToken is known to the sysmem server.
632 ///
633 /// This can be used in cases where BindSharedCollection() won't be called
634 /// until after BufferCollectionToken.Duplicate() +
635 /// BufferCollectionToken.Sync(), when the client code wants to know earlier
636 /// whether an incoming token is valid (so far).
637 ///
638 /// Calling BufferCollectionToken.Sync() on a token that isn't known to
639 /// sysmem risks the Sync() hanging forever.
640 ///
641 /// Given that an incoming token can become invalid at any time if any
642 /// participant drops their BufferCollectionToken(s) or BufferCollection(s),
643 /// authors of client code are encouraged to consider not calling
644 /// ValidateBufferCollectionToken() and instead dealing with async failure
645 /// of the BufferCollection.Sync() after all the
646 /// BufferCollectionToken.Duplicate() and BindSharedCollection() (before
647 /// sending any duplicate tokens to other processes).
648 ///
649 /// Regardless of the result of this call, this call has no effect on the
650 /// token with the referenced koid.
651 ///
652 /// A true result from this call doesn't guarantee that the token remains
653 /// valid for any duration afterwards.
654 ///
655 /// Client code will zx_object_get_info() on the client's token handle,
656 /// passing ZX_INFO_HANDLE_BASIC and getting back the related_koid
657 /// which then gets passed to ValidateBufferCollectionToken().
658 ///
659 /// If ValidateBufferCollectionToken() returns true, the token was known at
660 /// the time the sysmem server processed the call, but may no longer be
661 /// valid/known by the time the client code receives the response.
662 ///
663 /// If ValidateBufferCollectionToken() returns false, the token wasn't known
664 /// at the time the sysmem server processed the call, but the token may
665 /// become known by the time the client code receives the response. However
666 /// client code is not required to mitigate the possibility that the token
667 /// may become known late, since the source of the token should have synced
668 /// the token to sysmem before sending the token to the client code.
669 ///
670 /// If calling ValidateBufferCollectionToken() fails in some way, there will
671 /// be a zx_status_t from the FIDL layer.
672 ///
673 /// `token_server_koid` the koid of the server end of a channel that might
674 /// be a BufferCollectionToken channel. This can be obtained from
675 /// zx_object_get_info() ZX_INFO_HANDLE_BASIC related_koid.
676 pub fn r#validate_buffer_collection_token(
677 &self,
678 mut token_server_koid: u64,
679 ) -> fidl::client::QueryResponseFut<bool, fidl::encoding::DefaultFuchsiaResourceDialect> {
680 AllocatorProxyInterface::r#validate_buffer_collection_token(self, token_server_koid)
681 }
682
683 /// Set information about the current client that can be used by sysmem to
684 /// help debug leaking memory and hangs waiting for constraints. |name| can
685 /// be an arbitrary string, but the current process name (see
686 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
687 /// arbitrary id, but the current process ID (see
688 /// fsl::GetCurrentProcessKoid()) is a good default.
689 ///
690 /// This information is propagated to all BufferCollections created using
691 /// BindSharedCollection() or AllocateNonSharedCollection() from this
692 /// allocator. It does not affect BufferCollectionTokens, since they are
693 /// often passed cross-process and should have their names managed manually.
694 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
695 AllocatorProxyInterface::r#set_debug_client_info(self, name, id)
696 }
697
698 /// This allows creating a sysmem2 `Allocator` given a sysmem(1)
699 /// `Allocator`.
700 ///
701 /// This is mainly useful in situations where library code is handed a
702 /// sysmem(1) allocator, but the library code has been updated to use
703 /// sysmem2. Typically the library will provide a way to pass in a sysmem2
704 /// `Allocator` instead, but client code isn't always in the same repo, so
705 /// this message allows the library to still accept the sysmem(1) Allocator
706 /// temporarily.
707 ///
708 /// The info set via `SetDebugClientInfo` (if any) is copied to the sysmem2
709 /// `Allocator`.
710 pub fn r#connect_to_sysmem2_allocator(
711 &self,
712 mut allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
713 ) -> Result<(), fidl::Error> {
714 AllocatorProxyInterface::r#connect_to_sysmem2_allocator(self, allocator_request)
715 }
716}
717
718impl AllocatorProxyInterface for AllocatorProxy {
719 fn r#allocate_non_shared_collection(
720 &self,
721 mut collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
722 ) -> Result<(), fidl::Error> {
723 self.client.send::<AllocatorAllocateNonSharedCollectionRequest>(
724 (collection_request,),
725 0x20f79299bbb4d2c6,
726 fidl::encoding::DynamicFlags::empty(),
727 )
728 }
729
730 fn r#allocate_shared_collection(
731 &self,
732 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
733 ) -> Result<(), fidl::Error> {
734 self.client.send::<AllocatorAllocateSharedCollectionRequest>(
735 (token_request,),
736 0x7a757a57bfda0f71,
737 fidl::encoding::DynamicFlags::empty(),
738 )
739 }
740
741 fn r#bind_shared_collection(
742 &self,
743 mut token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
744 mut buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
745 ) -> Result<(), fidl::Error> {
746 self.client.send::<AllocatorBindSharedCollectionRequest>(
747 (token, buffer_collection_request),
748 0x146eca7ec46ff4ee,
749 fidl::encoding::DynamicFlags::empty(),
750 )
751 }
752
753 type ValidateBufferCollectionTokenResponseFut =
754 fidl::client::QueryResponseFut<bool, fidl::encoding::DefaultFuchsiaResourceDialect>;
755 fn r#validate_buffer_collection_token(
756 &self,
757 mut token_server_koid: u64,
758 ) -> Self::ValidateBufferCollectionTokenResponseFut {
759 fn _decode(
760 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
761 ) -> Result<bool, fidl::Error> {
762 let _response = fidl::client::decode_transaction_body::<
763 AllocatorValidateBufferCollectionTokenResponse,
764 fidl::encoding::DefaultFuchsiaResourceDialect,
765 0x575b279b0236faea,
766 >(_buf?)?;
767 Ok(_response.is_known)
768 }
769 self.client.send_query_and_decode::<AllocatorValidateBufferCollectionTokenRequest, bool>(
770 (token_server_koid,),
771 0x575b279b0236faea,
772 fidl::encoding::DynamicFlags::empty(),
773 _decode,
774 )
775 }
776
777 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
778 self.client.send::<AllocatorSetDebugClientInfoRequest>(
779 (name, id),
780 0x419f0d5b30728b26,
781 fidl::encoding::DynamicFlags::empty(),
782 )
783 }
784
785 fn r#connect_to_sysmem2_allocator(
786 &self,
787 mut allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
788 ) -> Result<(), fidl::Error> {
789 self.client.send::<AllocatorConnectToSysmem2AllocatorRequest>(
790 (allocator_request,),
791 0x13db3e3abac2e24,
792 fidl::encoding::DynamicFlags::empty(),
793 )
794 }
795}
796
797pub struct AllocatorEventStream {
798 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
799}
800
801impl std::marker::Unpin for AllocatorEventStream {}
802
803impl futures::stream::FusedStream for AllocatorEventStream {
804 fn is_terminated(&self) -> bool {
805 self.event_receiver.is_terminated()
806 }
807}
808
809impl futures::Stream for AllocatorEventStream {
810 type Item = Result<AllocatorEvent, fidl::Error>;
811
812 fn poll_next(
813 mut self: std::pin::Pin<&mut Self>,
814 cx: &mut std::task::Context<'_>,
815 ) -> std::task::Poll<Option<Self::Item>> {
816 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
817 &mut self.event_receiver,
818 cx
819 )?) {
820 Some(buf) => std::task::Poll::Ready(Some(AllocatorEvent::decode(buf))),
821 None => std::task::Poll::Ready(None),
822 }
823 }
824}
825
826#[derive(Debug)]
827pub enum AllocatorEvent {}
828
829impl AllocatorEvent {
830 /// Decodes a message buffer as a [`AllocatorEvent`].
831 fn decode(
832 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
833 ) -> Result<AllocatorEvent, fidl::Error> {
834 let (bytes, _handles) = buf.split_mut();
835 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
836 debug_assert_eq!(tx_header.tx_id, 0);
837 match tx_header.ordinal {
838 _ => Err(fidl::Error::UnknownOrdinal {
839 ordinal: tx_header.ordinal,
840 protocol_name: <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
841 }),
842 }
843 }
844}
845
846/// A Stream of incoming requests for fuchsia.sysmem/Allocator.
847pub struct AllocatorRequestStream {
848 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
849 is_terminated: bool,
850}
851
852impl std::marker::Unpin for AllocatorRequestStream {}
853
854impl futures::stream::FusedStream for AllocatorRequestStream {
855 fn is_terminated(&self) -> bool {
856 self.is_terminated
857 }
858}
859
860impl fidl::endpoints::RequestStream for AllocatorRequestStream {
861 type Protocol = AllocatorMarker;
862 type ControlHandle = AllocatorControlHandle;
863
864 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
865 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
866 }
867
868 fn control_handle(&self) -> Self::ControlHandle {
869 AllocatorControlHandle { inner: self.inner.clone() }
870 }
871
872 fn into_inner(
873 self,
874 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
875 {
876 (self.inner, self.is_terminated)
877 }
878
879 fn from_inner(
880 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
881 is_terminated: bool,
882 ) -> Self {
883 Self { inner, is_terminated }
884 }
885}
886
887impl futures::Stream for AllocatorRequestStream {
888 type Item = Result<AllocatorRequest, fidl::Error>;
889
890 fn poll_next(
891 mut self: std::pin::Pin<&mut Self>,
892 cx: &mut std::task::Context<'_>,
893 ) -> std::task::Poll<Option<Self::Item>> {
894 let this = &mut *self;
895 if this.inner.check_shutdown(cx) {
896 this.is_terminated = true;
897 return std::task::Poll::Ready(None);
898 }
899 if this.is_terminated {
900 panic!("polled AllocatorRequestStream after completion");
901 }
902 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
903 |bytes, handles| {
904 match this.inner.channel().read_etc(cx, bytes, handles) {
905 std::task::Poll::Ready(Ok(())) => {}
906 std::task::Poll::Pending => return std::task::Poll::Pending,
907 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
908 this.is_terminated = true;
909 return std::task::Poll::Ready(None);
910 }
911 std::task::Poll::Ready(Err(e)) => {
912 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
913 e.into(),
914 ))));
915 }
916 }
917
918 // A message has been received from the channel
919 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
920
921 std::task::Poll::Ready(Some(match header.ordinal {
922 0x20f79299bbb4d2c6 => {
923 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
924 let mut req = fidl::new_empty!(
925 AllocatorAllocateNonSharedCollectionRequest,
926 fidl::encoding::DefaultFuchsiaResourceDialect
927 );
928 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorAllocateNonSharedCollectionRequest>(&header, _body_bytes, handles, &mut req)?;
929 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
930 Ok(AllocatorRequest::AllocateNonSharedCollection {
931 collection_request: req.collection_request,
932
933 control_handle,
934 })
935 }
936 0x7a757a57bfda0f71 => {
937 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
938 let mut req = fidl::new_empty!(
939 AllocatorAllocateSharedCollectionRequest,
940 fidl::encoding::DefaultFuchsiaResourceDialect
941 );
942 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorAllocateSharedCollectionRequest>(&header, _body_bytes, handles, &mut req)?;
943 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
944 Ok(AllocatorRequest::AllocateSharedCollection {
945 token_request: req.token_request,
946
947 control_handle,
948 })
949 }
950 0x146eca7ec46ff4ee => {
951 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
952 let mut req = fidl::new_empty!(
953 AllocatorBindSharedCollectionRequest,
954 fidl::encoding::DefaultFuchsiaResourceDialect
955 );
956 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorBindSharedCollectionRequest>(&header, _body_bytes, handles, &mut req)?;
957 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
958 Ok(AllocatorRequest::BindSharedCollection {
959 token: req.token,
960 buffer_collection_request: req.buffer_collection_request,
961
962 control_handle,
963 })
964 }
965 0x575b279b0236faea => {
966 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
967 let mut req = fidl::new_empty!(
968 AllocatorValidateBufferCollectionTokenRequest,
969 fidl::encoding::DefaultFuchsiaResourceDialect
970 );
971 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorValidateBufferCollectionTokenRequest>(&header, _body_bytes, handles, &mut req)?;
972 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
973 Ok(AllocatorRequest::ValidateBufferCollectionToken {
974 token_server_koid: req.token_server_koid,
975
976 responder: AllocatorValidateBufferCollectionTokenResponder {
977 control_handle: std::mem::ManuallyDrop::new(control_handle),
978 tx_id: header.tx_id,
979 },
980 })
981 }
982 0x419f0d5b30728b26 => {
983 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
984 let mut req = fidl::new_empty!(
985 AllocatorSetDebugClientInfoRequest,
986 fidl::encoding::DefaultFuchsiaResourceDialect
987 );
988 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
989 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
990 Ok(AllocatorRequest::SetDebugClientInfo {
991 name: req.name,
992 id: req.id,
993
994 control_handle,
995 })
996 }
997 0x13db3e3abac2e24 => {
998 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
999 let mut req = fidl::new_empty!(
1000 AllocatorConnectToSysmem2AllocatorRequest,
1001 fidl::encoding::DefaultFuchsiaResourceDialect
1002 );
1003 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<AllocatorConnectToSysmem2AllocatorRequest>(&header, _body_bytes, handles, &mut req)?;
1004 let control_handle = AllocatorControlHandle { inner: this.inner.clone() };
1005 Ok(AllocatorRequest::ConnectToSysmem2Allocator {
1006 allocator_request: req.allocator_request,
1007
1008 control_handle,
1009 })
1010 }
1011 _ => Err(fidl::Error::UnknownOrdinal {
1012 ordinal: header.ordinal,
1013 protocol_name:
1014 <AllocatorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1015 }),
1016 }))
1017 },
1018 )
1019 }
1020}
1021
1022/// Allocates system memory buffers.
1023#[derive(Debug)]
1024pub enum AllocatorRequest {
1025 /// Allocates a BufferCollection on behalf of a single client (aka initiator)
1026 /// who is also the only participant (from the point of view of sysmem).
1027 ///
1028 /// This call exists mainly for temp/testing purposes. This call skips the
1029 /// BufferCollectionToken stage, so there's no way to allow another
1030 /// participant to specify its constraints.
1031 ///
1032 /// Real clients are encouraged to use AllocateSharedCollection() instead,
1033 /// and to let relevant participants directly convey their own constraints to
1034 /// sysmem.
1035 ///
1036 /// `collection_request` is the server end of the BufferCollection FIDL
1037 /// channel. The client can call SetConstraints() and then
1038 /// WaitForBuffersAllocated() on the client end of this channel to specify
1039 /// constraints and then determine success/failure and get the
1040 /// BufferCollectionInfo_2 for the BufferCollection. The client should also
1041 /// keep the client end of this channel open while using the
1042 /// BufferCollection, and should notice when this channel closes and stop
1043 /// using the BufferCollection ASAP.
1044 AllocateNonSharedCollection {
1045 collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
1046 control_handle: AllocatorControlHandle,
1047 },
1048 /// Creates a logical BufferCollectionToken which can be shared among
1049 /// participants (using BufferCollectionToken.Duplicate()), and then
1050 /// converted into a BufferCollection using BindSharedCollection().
1051 ///
1052 /// Success/failure to populate the BufferCollection with buffers is
1053 /// determined via the BufferCollection interface.
1054 AllocateSharedCollection {
1055 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
1056 control_handle: AllocatorControlHandle,
1057 },
1058 /// Convert a BufferCollectionToken into a connection to the logical
1059 /// BufferCollection. The BufferCollection hasn't yet been populated with
1060 /// buffers - the participant must first also send SetConstraints() via the
1061 /// client end of buffer_collection.
1062 ///
1063 /// All BufferCollectionToken(s) duplicated from a logical
1064 /// BufferCollectionToken created via AllocateSharedCollection() must be
1065 /// turned in via BindSharedCollection() before the logical BufferCollection
1066 /// will be populated with buffers.
1067 ///
1068 /// `token` the client endpoint of a channel whose server end was sent to
1069 /// sysmem using AllocateSharedCollection or whose server end was sent to
1070 /// sysmem using BufferCollectionToken.Duplicate(). The token is being
1071 /// "exchanged" for a channel to the logical BufferCollection.
1072 ///
1073 /// `buffer_collection_request` the server end of a BufferCollection
1074 /// channel. The sender retains the client end as usual. The
1075 /// BufferCollection channel is a single participant's connection to the
1076 /// logical BufferCollection. There typically will be other participants
1077 /// with their own BufferCollection channel to the logical BufferCollection.
1078 BindSharedCollection {
1079 token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
1080 buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
1081 control_handle: AllocatorControlHandle,
1082 },
1083 /// Validate that a BufferCollectionToken is known to the sysmem server.
1084 ///
1085 /// This can be used in cases where BindSharedCollection() won't be called
1086 /// until after BufferCollectionToken.Duplicate() +
1087 /// BufferCollectionToken.Sync(), when the client code wants to know earlier
1088 /// whether an incoming token is valid (so far).
1089 ///
1090 /// Calling BufferCollectionToken.Sync() on a token that isn't known to
1091 /// sysmem risks the Sync() hanging forever.
1092 ///
1093 /// Given that an incoming token can become invalid at any time if any
1094 /// participant drops their BufferCollectionToken(s) or BufferCollection(s),
1095 /// authors of client code are encouraged to consider not calling
1096 /// ValidateBufferCollectionToken() and instead dealing with async failure
1097 /// of the BufferCollection.Sync() after all the
1098 /// BufferCollectionToken.Duplicate() and BindSharedCollection() (before
1099 /// sending any duplicate tokens to other processes).
1100 ///
1101 /// Regardless of the result of this call, this call has no effect on the
1102 /// token with the referenced koid.
1103 ///
1104 /// A true result from this call doesn't guarantee that the token remains
1105 /// valid for any duration afterwards.
1106 ///
1107 /// Client code will zx_object_get_info() on the client's token handle,
1108 /// passing ZX_INFO_HANDLE_BASIC and getting back the related_koid
1109 /// which then gets passed to ValidateBufferCollectionToken().
1110 ///
1111 /// If ValidateBufferCollectionToken() returns true, the token was known at
1112 /// the time the sysmem server processed the call, but may no longer be
1113 /// valid/known by the time the client code receives the response.
1114 ///
1115 /// If ValidateBufferCollectionToken() returns false, the token wasn't known
1116 /// at the time the sysmem server processed the call, but the token may
1117 /// become known by the time the client code receives the response. However
1118 /// client code is not required to mitigate the possibility that the token
1119 /// may become known late, since the source of the token should have synced
1120 /// the token to sysmem before sending the token to the client code.
1121 ///
1122 /// If calling ValidateBufferCollectionToken() fails in some way, there will
1123 /// be a zx_status_t from the FIDL layer.
1124 ///
1125 /// `token_server_koid` the koid of the server end of a channel that might
1126 /// be a BufferCollectionToken channel. This can be obtained from
1127 /// zx_object_get_info() ZX_INFO_HANDLE_BASIC related_koid.
1128 ValidateBufferCollectionToken {
1129 token_server_koid: u64,
1130 responder: AllocatorValidateBufferCollectionTokenResponder,
1131 },
1132 /// Set information about the current client that can be used by sysmem to
1133 /// help debug leaking memory and hangs waiting for constraints. |name| can
1134 /// be an arbitrary string, but the current process name (see
1135 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
1136 /// arbitrary id, but the current process ID (see
1137 /// fsl::GetCurrentProcessKoid()) is a good default.
1138 ///
1139 /// This information is propagated to all BufferCollections created using
1140 /// BindSharedCollection() or AllocateNonSharedCollection() from this
1141 /// allocator. It does not affect BufferCollectionTokens, since they are
1142 /// often passed cross-process and should have their names managed manually.
1143 SetDebugClientInfo { name: String, id: u64, control_handle: AllocatorControlHandle },
1144 /// This allows creating a sysmem2 `Allocator` given a sysmem(1)
1145 /// `Allocator`.
1146 ///
1147 /// This is mainly useful in situations where library code is handed a
1148 /// sysmem(1) allocator, but the library code has been updated to use
1149 /// sysmem2. Typically the library will provide a way to pass in a sysmem2
1150 /// `Allocator` instead, but client code isn't always in the same repo, so
1151 /// this message allows the library to still accept the sysmem(1) Allocator
1152 /// temporarily.
1153 ///
1154 /// The info set via `SetDebugClientInfo` (if any) is copied to the sysmem2
1155 /// `Allocator`.
1156 ConnectToSysmem2Allocator {
1157 allocator_request: fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
1158 control_handle: AllocatorControlHandle,
1159 },
1160}
1161
1162impl AllocatorRequest {
1163 #[allow(irrefutable_let_patterns)]
1164 pub fn into_allocate_non_shared_collection(
1165 self,
1166 ) -> Option<(fidl::endpoints::ServerEnd<BufferCollectionMarker>, AllocatorControlHandle)> {
1167 if let AllocatorRequest::AllocateNonSharedCollection {
1168 collection_request,
1169 control_handle,
1170 } = self
1171 {
1172 Some((collection_request, control_handle))
1173 } else {
1174 None
1175 }
1176 }
1177
1178 #[allow(irrefutable_let_patterns)]
1179 pub fn into_allocate_shared_collection(
1180 self,
1181 ) -> Option<(fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>, AllocatorControlHandle)>
1182 {
1183 if let AllocatorRequest::AllocateSharedCollection { token_request, control_handle } = self {
1184 Some((token_request, control_handle))
1185 } else {
1186 None
1187 }
1188 }
1189
1190 #[allow(irrefutable_let_patterns)]
1191 pub fn into_bind_shared_collection(
1192 self,
1193 ) -> Option<(
1194 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
1195 fidl::endpoints::ServerEnd<BufferCollectionMarker>,
1196 AllocatorControlHandle,
1197 )> {
1198 if let AllocatorRequest::BindSharedCollection {
1199 token,
1200 buffer_collection_request,
1201 control_handle,
1202 } = self
1203 {
1204 Some((token, buffer_collection_request, control_handle))
1205 } else {
1206 None
1207 }
1208 }
1209
1210 #[allow(irrefutable_let_patterns)]
1211 pub fn into_validate_buffer_collection_token(
1212 self,
1213 ) -> Option<(u64, AllocatorValidateBufferCollectionTokenResponder)> {
1214 if let AllocatorRequest::ValidateBufferCollectionToken { token_server_koid, responder } =
1215 self
1216 {
1217 Some((token_server_koid, responder))
1218 } else {
1219 None
1220 }
1221 }
1222
1223 #[allow(irrefutable_let_patterns)]
1224 pub fn into_set_debug_client_info(self) -> Option<(String, u64, AllocatorControlHandle)> {
1225 if let AllocatorRequest::SetDebugClientInfo { name, id, control_handle } = self {
1226 Some((name, id, control_handle))
1227 } else {
1228 None
1229 }
1230 }
1231
1232 #[allow(irrefutable_let_patterns)]
1233 pub fn into_connect_to_sysmem2_allocator(
1234 self,
1235 ) -> Option<(
1236 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
1237 AllocatorControlHandle,
1238 )> {
1239 if let AllocatorRequest::ConnectToSysmem2Allocator { allocator_request, control_handle } =
1240 self
1241 {
1242 Some((allocator_request, control_handle))
1243 } else {
1244 None
1245 }
1246 }
1247
1248 /// Name of the method defined in FIDL
1249 pub fn method_name(&self) -> &'static str {
1250 match *self {
1251 AllocatorRequest::AllocateNonSharedCollection { .. } => {
1252 "allocate_non_shared_collection"
1253 }
1254 AllocatorRequest::AllocateSharedCollection { .. } => "allocate_shared_collection",
1255 AllocatorRequest::BindSharedCollection { .. } => "bind_shared_collection",
1256 AllocatorRequest::ValidateBufferCollectionToken { .. } => {
1257 "validate_buffer_collection_token"
1258 }
1259 AllocatorRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
1260 AllocatorRequest::ConnectToSysmem2Allocator { .. } => "connect_to_sysmem2_allocator",
1261 }
1262 }
1263}
1264
1265#[derive(Debug, Clone)]
1266pub struct AllocatorControlHandle {
1267 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1268}
1269
1270impl fidl::endpoints::ControlHandle for AllocatorControlHandle {
1271 fn shutdown(&self) {
1272 self.inner.shutdown()
1273 }
1274 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
1275 self.inner.shutdown_with_epitaph(status)
1276 }
1277
1278 fn is_closed(&self) -> bool {
1279 self.inner.channel().is_closed()
1280 }
1281 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1282 self.inner.channel().on_closed()
1283 }
1284
1285 #[cfg(target_os = "fuchsia")]
1286 fn signal_peer(
1287 &self,
1288 clear_mask: zx::Signals,
1289 set_mask: zx::Signals,
1290 ) -> Result<(), zx_status::Status> {
1291 use fidl::Peered;
1292 self.inner.channel().signal_peer(clear_mask, set_mask)
1293 }
1294}
1295
1296impl AllocatorControlHandle {}
1297
1298#[must_use = "FIDL methods require a response to be sent"]
1299#[derive(Debug)]
1300pub struct AllocatorValidateBufferCollectionTokenResponder {
1301 control_handle: std::mem::ManuallyDrop<AllocatorControlHandle>,
1302 tx_id: u32,
1303}
1304
1305/// Set the the channel to be shutdown (see [`AllocatorControlHandle::shutdown`])
1306/// if the responder is dropped without sending a response, so that the client
1307/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1308impl std::ops::Drop for AllocatorValidateBufferCollectionTokenResponder {
1309 fn drop(&mut self) {
1310 self.control_handle.shutdown();
1311 // Safety: drops once, never accessed again
1312 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1313 }
1314}
1315
1316impl fidl::endpoints::Responder for AllocatorValidateBufferCollectionTokenResponder {
1317 type ControlHandle = AllocatorControlHandle;
1318
1319 fn control_handle(&self) -> &AllocatorControlHandle {
1320 &self.control_handle
1321 }
1322
1323 fn drop_without_shutdown(mut self) {
1324 // Safety: drops once, never accessed again due to mem::forget
1325 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1326 // Prevent Drop from running (which would shut down the channel)
1327 std::mem::forget(self);
1328 }
1329}
1330
1331impl AllocatorValidateBufferCollectionTokenResponder {
1332 /// Sends a response to the FIDL transaction.
1333 ///
1334 /// Sets the channel to shutdown if an error occurs.
1335 pub fn send(self, mut is_known: bool) -> Result<(), fidl::Error> {
1336 let _result = self.send_raw(is_known);
1337 if _result.is_err() {
1338 self.control_handle.shutdown();
1339 }
1340 self.drop_without_shutdown();
1341 _result
1342 }
1343
1344 /// Similar to "send" but does not shutdown the channel if an error occurs.
1345 pub fn send_no_shutdown_on_err(self, mut is_known: bool) -> Result<(), fidl::Error> {
1346 let _result = self.send_raw(is_known);
1347 self.drop_without_shutdown();
1348 _result
1349 }
1350
1351 fn send_raw(&self, mut is_known: bool) -> Result<(), fidl::Error> {
1352 self.control_handle.inner.send::<AllocatorValidateBufferCollectionTokenResponse>(
1353 (is_known,),
1354 self.tx_id,
1355 0x575b279b0236faea,
1356 fidl::encoding::DynamicFlags::empty(),
1357 )
1358 }
1359}
1360
1361#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1362pub struct BufferCollectionMarker;
1363
1364impl fidl::endpoints::ProtocolMarker for BufferCollectionMarker {
1365 type Proxy = BufferCollectionProxy;
1366 type RequestStream = BufferCollectionRequestStream;
1367 #[cfg(target_os = "fuchsia")]
1368 type SynchronousProxy = BufferCollectionSynchronousProxy;
1369
1370 const DEBUG_NAME: &'static str = "(anonymous) BufferCollection";
1371}
1372
1373pub trait BufferCollectionProxyInterface: Send + Sync {
1374 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
1375 fn r#sync(&self) -> Self::SyncResponseFut;
1376 fn r#close(&self) -> Result<(), fidl::Error>;
1377 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
1378 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
1379 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
1380 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
1381 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
1382 + Send;
1383 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
1384 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
1385 + Send;
1386 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
1387 fn r#set_constraints(
1388 &self,
1389 has_constraints: bool,
1390 constraints: &BufferCollectionConstraints,
1391 ) -> Result<(), fidl::Error>;
1392 type WaitForBuffersAllocatedResponseFut: std::future::Future<Output = Result<(i32, BufferCollectionInfo2), fidl::Error>>
1393 + Send;
1394 fn r#wait_for_buffers_allocated(&self) -> Self::WaitForBuffersAllocatedResponseFut;
1395 type CheckBuffersAllocatedResponseFut: std::future::Future<Output = Result<i32, fidl::Error>>
1396 + Send;
1397 fn r#check_buffers_allocated(&self) -> Self::CheckBuffersAllocatedResponseFut;
1398 fn r#attach_token(
1399 &self,
1400 rights_attenuation_mask: u32,
1401 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
1402 ) -> Result<(), fidl::Error>;
1403 fn r#attach_lifetime_tracking(
1404 &self,
1405 server_end: fidl::EventPair,
1406 buffers_remaining: u32,
1407 ) -> Result<(), fidl::Error>;
1408}
1409#[derive(Debug)]
1410#[cfg(target_os = "fuchsia")]
1411pub struct BufferCollectionSynchronousProxy {
1412 client: fidl::client::sync::Client,
1413}
1414
1415#[cfg(target_os = "fuchsia")]
1416impl fidl::endpoints::SynchronousProxy for BufferCollectionSynchronousProxy {
1417 type Proxy = BufferCollectionProxy;
1418 type Protocol = BufferCollectionMarker;
1419
1420 fn from_channel(inner: fidl::Channel) -> Self {
1421 Self::new(inner)
1422 }
1423
1424 fn into_channel(self) -> fidl::Channel {
1425 self.client.into_channel()
1426 }
1427
1428 fn as_channel(&self) -> &fidl::Channel {
1429 self.client.as_channel()
1430 }
1431}
1432
1433#[cfg(target_os = "fuchsia")]
1434impl BufferCollectionSynchronousProxy {
1435 pub fn new(channel: fidl::Channel) -> Self {
1436 let protocol_name = <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
1437 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
1438 }
1439
1440 pub fn into_channel(self) -> fidl::Channel {
1441 self.client.into_channel()
1442 }
1443
1444 /// Waits until an event arrives and returns it. It is safe for other
1445 /// threads to make concurrent requests while waiting for an event.
1446 pub fn wait_for_event(
1447 &self,
1448 deadline: zx::MonotonicInstant,
1449 ) -> Result<BufferCollectionEvent, fidl::Error> {
1450 BufferCollectionEvent::decode(self.client.wait_for_event(deadline)?)
1451 }
1452
1453 /// Ensure that previous messages, including Duplicate() messages on a
1454 /// token, collection, or group, have been received server side.
1455 ///
1456 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
1457 /// valid sysmem token risks the Sync() hanging forever. See
1458 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
1459 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
1460 /// Another way is to pass the token to BindSharedCollection(), which also
1461 /// validates the token as part of exchanging it for a BufferCollection
1462 /// channel, and BufferCollection Sync() can then be used.
1463 ///
1464 /// After a Sync(), it's then safe to send the client end of token_request
1465 /// to another participant knowing the server will recognize the token when
1466 /// it's sent into BindSharedCollection() by the other participant.
1467 ///
1468 /// Other options include waiting for each token.Duplicate() to complete
1469 /// individually (using separate call to token.Sync() after each), or
1470 /// calling Sync() on BufferCollection after the token has been turned in
1471 /// via BindSharedCollection().
1472 ///
1473 /// Another way to mitigate is to avoid calling Sync() on the token, and
1474 /// instead later deal with potential failure of BufferCollection.Sync() if
1475 /// the original token was invalid. This option can be preferable from a
1476 /// performance point of view, but requires client code to delay sending
1477 /// tokens duplicated from this token until after client code has converted
1478 /// the duplicating token to a BufferCollection and received successful
1479 /// response from BufferCollection.Sync().
1480 ///
1481 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
1482 /// When BufferCollection.Sync() isn't feasible, the caller must already
1483 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
1484 /// hang forever. See ValidateBufferCollectionToken() to check token
1485 /// validity first if the token isn't already known to be (is/was) valid.
1486 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
1487 let _response =
1488 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
1489 (),
1490 0x4577e238ae26291,
1491 fidl::encoding::DynamicFlags::empty(),
1492 ___deadline,
1493 )?;
1494 Ok(_response)
1495 }
1496
1497 /// On a BufferCollectionToken channel:
1498 ///
1499 /// Normally a participant will convert a BufferCollectionToken into a
1500 /// BufferCollection view, but a participant is also free to Close() the
1501 /// token (and then close the channel immediately or shortly later in
1502 /// response to server closing its end), which avoids causing logical buffer
1503 /// collection failure. Â Normally an unexpected token channel close will
1504 /// cause logical buffer collection failure (the only exceptions being
1505 /// certain cases involving AttachToken() or SetDispensable()).
1506 ///
1507 /// On a BufferCollection channel:
1508 ///
1509 /// By default the server handles unexpected failure of a BufferCollection
1510 /// by failing the whole logical buffer collection. Partly this is to
1511 /// expedite closing VMO handles to reclaim memory when any participant
1512 /// fails. If a participant would like to cleanly close a BufferCollection
1513 /// view without causing logical buffer collection failure, the participant
1514 /// can send Close() before closing the client end of the BufferCollection
1515 /// channel. If this is the last BufferCollection view, the logical buffer
1516 /// collection will still go away. The Close() can occur before or after
1517 /// SetConstraints(). If before SetConstraints(), the buffer collection
1518 /// won't require constraints from this node in order to allocate. If
1519 /// after SetConstraints(), the constraints are retained and aggregated
1520 /// along with any subsequent logical allocation(s), despite the lack of
1521 /// channel connection.
1522 ///
1523 /// On a BufferCollectionTokenGroup channel:
1524 ///
1525 /// By default, unexpected failure of a BufferCollectionTokenGroup will
1526 /// trigger failure of the logical BufferCollectionTokenGroup and will
1527 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
1528 /// channel without failing the logical group or propagating failure, send
1529 /// Close() before closing the channel client endpoint.
1530 ///
1531 /// If Close() occurs before AllChildrenPresent(), the logical buffer
1532 /// collection will still fail despite the Close() (because sysmem can't be
1533 /// sure whether all relevant children were created, so it's ambiguous
1534 /// whether all relevant constraints will be provided to sysmem). If
1535 /// Close() occurs after AllChildrenPresent(), the children and all their
1536 /// constraints remain intact (just as they would if the
1537 /// BufferCollectionTokenGroup channel had remained open), and the close
1538 /// doesn't trigger or propagate failure.
1539 pub fn r#close(&self) -> Result<(), fidl::Error> {
1540 self.client.send::<fidl::encoding::EmptyPayload>(
1541 (),
1542 0x5b1d7a4f5681fca7,
1543 fidl::encoding::DynamicFlags::empty(),
1544 )
1545 }
1546
1547 /// Set a name for VMOs in this buffer collection. The name may be truncated
1548 /// shorter. The name only affects VMOs allocated after it's set - this call
1549 /// does not rename existing VMOs. If multiple clients set different names
1550 /// then the larger priority value will win.
1551 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
1552 self.client.send::<NodeSetNameRequest>(
1553 (priority, name),
1554 0x77a41bb6217e2443,
1555 fidl::encoding::DynamicFlags::empty(),
1556 )
1557 }
1558
1559 /// Set information about the current client that can be used by sysmem to
1560 /// help debug leaking memory and hangs waiting for constraints. |name| can
1561 /// be an arbitrary string, but the current process name (see
1562 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
1563 /// arbitrary id, but the current process ID (see
1564 /// fsl::GetCurrentProcessKoid()) is a good default.
1565 ///
1566 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
1567 /// indicate which client is closing their channel first, leading to
1568 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
1569 /// over, but if happening earlier than expected, the
1570 /// client-channel-specific name can help diagnose where the failure is
1571 /// first coming from, from sysmem's point of view).
1572 ///
1573 /// By default (unless overriden by this message or using
1574 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
1575 /// parent Node at the time the child Node is created. While this can be
1576 /// better than nothing, it's often better for each participant to use
1577 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
1578 /// info directly relevant to the current client. Also, SetVerboseLogging()
1579 /// can be used to help disambiguate if a Node is suspected of having info
1580 /// that was copied from its parent.
1581 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
1582 self.client.send::<NodeSetDebugClientInfoRequest>(
1583 (name, id),
1584 0x7275759070eb5ee2,
1585 fidl::encoding::DynamicFlags::empty(),
1586 )
1587 }
1588
1589 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
1590 /// after creating a collection. Clients can call this method to change
1591 /// when the log is printed. If multiple client set the deadline, it's
1592 /// unspecified which deadline will take effect.
1593 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
1594 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
1595 (deadline,),
1596 0x46d38f4772638867,
1597 fidl::encoding::DynamicFlags::empty(),
1598 )
1599 }
1600
1601 /// Verbose logging includes constraints set via SetConstraints() from each
1602 /// client along with info set via SetDebugClientInfo() and the structure of
1603 /// the tree of Node(s).
1604 ///
1605 /// Normally sysmem prints only a single line complaint when aggregation
1606 /// fails, with just the specific detailed reason that aggregation failed,
1607 /// with minimal context. While this is often enough to diagnose a problem
1608 /// if only a small change was made and the system had been working before
1609 /// the small change, it's often not particularly helpful for getting a new
1610 /// buffer collection to work for the first time. Especially with more
1611 /// complex trees of nodes, involving things like AttachToken(),
1612 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
1613 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
1614 /// looks like and why it's failing a logical allocation, or why a tree or
1615 /// sub-tree is failing sooner than expected.
1616 ///
1617 /// The intent of the extra logging is to be acceptable from a performance
1618 /// point of view, if only enabled on a low number of buffer collections.
1619 /// If we're not tracking down a bug, we shouldn't send this message.
1620 ///
1621 /// If too many participants leave verbose logging enabled, we may end up
1622 /// needing to require that system-wide sysmem verbose logging be permitted
1623 /// via some other setting, to avoid sysmem spamming the log too much due to
1624 /// this message.
1625 ///
1626 /// This may be a NOP for some nodes due to intentional policy associated
1627 /// with the node, if we don't trust a node enough to let it turn on verbose
1628 /// logging.
1629 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
1630 self.client.send::<fidl::encoding::EmptyPayload>(
1631 (),
1632 0x6bfbe2cf1701d288,
1633 fidl::encoding::DynamicFlags::empty(),
1634 )
1635 }
1636
1637 /// This gets an event handle that can be used as a parameter to
1638 /// IsAlternateFor() called on any Node. The client will not be granted the
1639 /// right to signal this event, as this handle should only be used as proof
1640 /// that the client obtained this handle from this Node.
1641 ///
1642 /// Because this is a get not a set, no Sync() is needed between the
1643 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
1644 /// potentially being on different channels.
1645 ///
1646 /// See also IsAlternateFor().
1647 pub fn r#get_node_ref(
1648 &self,
1649 ___deadline: zx::MonotonicInstant,
1650 ) -> Result<fidl::Event, fidl::Error> {
1651 let _response =
1652 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
1653 (),
1654 0x467b7c75c35c3b84,
1655 fidl::encoding::DynamicFlags::empty(),
1656 ___deadline,
1657 )?;
1658 Ok(_response.node_ref)
1659 }
1660
1661 /// This checks whether the calling node is in a subtree rooted at a
1662 /// different child token of a common parent BufferCollectionTokenGroup, in
1663 /// relation to the passed-in node_ref.
1664 ///
1665 /// This call is for assisting with admission control de-duplication, and
1666 /// with debugging.
1667 ///
1668 /// The node_ref must be obtained using GetNodeRef() of a
1669 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
1670 ///
1671 /// The node_ref can be a duplicated handle; it's not necessary to call
1672 /// GetNodeRef() for every call to IsAlternateFor().
1673 ///
1674 /// If a calling token may not actually be a valid token at all due to
1675 /// a potentially hostile/untrusted provider of the token, call
1676 /// ValidateBufferCollectionToken() first instead of potentially getting
1677 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
1678 /// token not being a real token (not really talking to sysmem). Another
1679 /// option is to call BindSharedCollection with this token first which also
1680 /// validates the token along with converting it to a BufferCollection, then
1681 /// call BufferCollection IsAlternateFor().
1682 ///
1683 /// error values:
1684 ///
1685 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
1686 /// buffer collection as the calling Node. Before logical allocation and
1687 /// within the same logical allocation sub-tree, this essentially means that
1688 /// the node_ref was never part of this logical buffer collection, since
1689 /// before logical allocation all node_refs that come into existence remain
1690 /// in existence at least until logical allocation (including Node(s) that
1691 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
1692 /// to be returned, this Node's channel needs to still be connected server
1693 /// side, which won't be the case if the whole logical allocation has
1694 /// failed. After logical allocation or in a different logical allocation
1695 /// sub-tree there are additional potential reasons for this error. For
1696 /// example a different logical allocation (separated from this Node(s)
1697 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
1698 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
1699 /// exist and may select a different child sub-tree than the sub-tree the
1700 /// node_ref is in causing deletion of the node_ref Node. The only time
1701 /// sysmem keeps a Node around after that Node has no corresponding channel
1702 /// is when Close() is used and the Node's sub-tree has not yet failed.
1703 /// Another reason for this error is if the node_ref is an eventpair handle
1704 /// with sufficient rights, but isn't actually a real node_ref obtained from
1705 /// GetNodeRef().
1706 ///
1707 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
1708 /// eventpair handle, or doesn't have the needed rights expected on a real
1709 /// node_ref.
1710 ///
1711 /// No other failing status codes are returned by this call. However,
1712 /// sysmem may add additional codes in future, so the client should have
1713 /// sensible default handling for any failing status code.
1714 ///
1715 /// On success, is_alternate has the following meaning:
1716 /// * true - The first parent node in common between the calling node and
1717 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
1718 /// the calling Node and the node_ref Node will _not_ have both their
1719 /// constraints apply - rather sysmem will choose one or the other of
1720 /// the constraints - never both. This is because only one child of
1721 /// a BufferCollectionTokenGroup is selected during logical allocation,
1722 /// with only that one child's sub-tree contributing to constraints
1723 /// aggregation.
1724 /// * false - The first parent node in common between the calling Node and
1725 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
1726 /// this means the first parent node in common is a
1727 /// BufferCollectionToken or BufferCollection (regardless of not
1728 /// Close()ed or Close()ed). This means that the calling Node and the
1729 /// node_ref Node _may_ have both their constraints apply during
1730 /// constraints aggregation of the logical allocation, if both Node(s)
1731 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
1732 /// In this case, there is no BufferCollectionTokenGroup that will
1733 /// directly prevent the two Node(s) from both being selected and their
1734 /// constraints both aggregated, but even when false, one or both
1735 /// Node(s) may still be eliminated from consideration if one or both
1736 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
1737 /// which selects a child sub-tree other than the sub-tree containing
1738 /// the calling Node or node_ref Node.
1739 pub fn r#is_alternate_for(
1740 &self,
1741 mut node_ref: fidl::Event,
1742 ___deadline: zx::MonotonicInstant,
1743 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
1744 let _response = self.client.send_query::<
1745 NodeIsAlternateForRequest,
1746 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
1747 >(
1748 (node_ref,),
1749 0x33a2a7aff2776c07,
1750 fidl::encoding::DynamicFlags::empty(),
1751 ___deadline,
1752 )?;
1753 Ok(_response.map(|x| x.is_alternate))
1754 }
1755
1756 /// Provide BufferCollectionConstraints to the logical BufferCollection.
1757 ///
1758 /// A participant may only call SetConstraints() once.
1759 ///
1760 /// Sometimes the initiator is a participant only in the sense of wanting to
1761 /// keep an eye on success/failure to populate with buffers, and zx.Status
1762 /// on failure. In that case, `has_constraints` can be false, and
1763 /// `constraints` will be ignored.
1764 ///
1765 /// VMO handles will not be provided to the client that sends null
1766 /// constraints - that can be intentional for an initiator that doesn't need
1767 /// VMO handles. Not having VMO handles doesn't prevent the initator from
1768 /// adjusting which portion of a buffer is considered valid and similar, but
1769 /// the initiator can't hold a VMO handle open to prevent the logical
1770 /// BufferCollection from cleaning up if the logical BufferCollection needs
1771 /// to go away regardless of the initiator's degree of involvement for
1772 /// whatever reason.
1773 ///
1774 /// For population of buffers to be attempted, all holders of a
1775 /// BufferCollection client channel need to call SetConstraints() before
1776 /// sysmem will attempt to allocate buffers.
1777 ///
1778 /// `has_constraints` if false, the constraints are effectively null, and
1779 /// `constraints` are ignored. The sender of null constraints won't get any
1780 /// VMO handles in BufferCollectionInfo, but can still find out how many
1781 /// buffers were allocated and can still refer to buffers by their
1782 /// buffer_index.
1783 ///
1784 /// `constraints` are constraints on the buffer collection.
1785 pub fn r#set_constraints(
1786 &self,
1787 mut has_constraints: bool,
1788 mut constraints: &BufferCollectionConstraints,
1789 ) -> Result<(), fidl::Error> {
1790 self.client.send::<BufferCollectionSetConstraintsRequest>(
1791 (has_constraints, constraints),
1792 0x4d9c3406c213227b,
1793 fidl::encoding::DynamicFlags::empty(),
1794 )
1795 }
1796
1797 /// This request completes when buffers have been allocated, responds with
1798 /// some failure detail if allocation has been attempted but failed.
1799 ///
1800 /// The following must occur before buffers will be allocated:
1801 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
1802 /// must be turned in via BindSharedCollection().
1803 /// * All BufferCollection(s) of the logical BufferCollection must have
1804 /// had SetConstraints() sent to them.
1805 ///
1806 /// Returns `ZX_OK` if successful.
1807 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
1808 /// fulfilled due to resource exhaustion.
1809 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
1810 /// obtain the buffers it requested.
1811 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
1812 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
1813 /// satisfied, perhaps due to hardware limitations.
1814 ///
1815 /// `buffer_collection_info` has the VMO handles and other related info.
1816 pub fn r#wait_for_buffers_allocated(
1817 &self,
1818 ___deadline: zx::MonotonicInstant,
1819 ) -> Result<(i32, BufferCollectionInfo2), fidl::Error> {
1820 let _response = self.client.send_query::<
1821 fidl::encoding::EmptyPayload,
1822 BufferCollectionWaitForBuffersAllocatedResponse,
1823 >(
1824 (),
1825 0x714667ea2a29a3a2,
1826 fidl::encoding::DynamicFlags::empty(),
1827 ___deadline,
1828 )?;
1829 Ok((_response.status, _response.buffer_collection_info))
1830 }
1831
1832 /// This returns the same result code as WaitForBuffersAllocated if the
1833 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
1834 /// if WaitForBuffersAllocated would block.
1835 pub fn r#check_buffers_allocated(
1836 &self,
1837 ___deadline: zx::MonotonicInstant,
1838 ) -> Result<i32, fidl::Error> {
1839 let _response = self.client.send_query::<
1840 fidl::encoding::EmptyPayload,
1841 BufferCollectionCheckBuffersAllocatedResponse,
1842 >(
1843 (),
1844 0x245bb81f79189e9,
1845 fidl::encoding::DynamicFlags::empty(),
1846 ___deadline,
1847 )?;
1848 Ok(_response.status)
1849 }
1850
1851 /// Create a new token, for trying to add a new participant to an existing
1852 /// collection, if the existing collection's buffer counts, constraints,
1853 /// and participants allow.
1854 ///
1855 /// This can be useful in replacing a failed participant, and/or in
1856 /// adding/re-adding a participant after buffers have already been
1857 /// allocated.
1858 ///
1859 /// Failure of an attached token / collection does not propagate to the
1860 /// parent of the attached token. Failure does propagate from a normal
1861 /// child of a dispensable token to the dispensable token. Failure
1862 /// of a child is blocked from reaching its parent if the child is attached,
1863 /// or if the child is dispensable and the failure occurred after logical
1864 /// allocation.
1865 ///
1866 /// An initiator may in some scenarios choose to initially use a dispensable
1867 /// token for a given instance of a participant, and then later if the first
1868 /// instance of that participant fails, a new second instance of that
1869 /// participant my be given a token created with AttachToken().
1870 ///
1871 /// From the point of view of the client end of the BufferCollectionToken
1872 /// channel, the token acts like any other token. The client can
1873 /// Duplicate() the token as needed, and can send the token to a different
1874 /// process. The token should be converted to a BufferCollection channel
1875 /// as normal by calling BindSharedCollection(). SetConstraints() should
1876 /// be called on that BufferCollection channel.
1877 ///
1878 /// A success result from WaitForBuffersAllocated() means the new
1879 /// participant's constraints were satisfiable using the already-existing
1880 /// buffer collection, the already-established BufferCollectionInfo
1881 /// including image format constraints, and the already-existing other
1882 /// participants and their buffer counts. A failure result means the new
1883 /// participant's constraints cannot be satisfied using the existing
1884 /// buffer collection and its already-logically-allocated participants.
1885 /// Creating a new collection instead may allow all participant's
1886 /// constraints to be satisfied, assuming SetDispensable() is used in place
1887 /// of AttachToken(), or a normal token is used.
1888 ///
1889 /// A token created with AttachToken() performs constraints aggregation with
1890 /// all constraints currently in effect on the buffer collection, plus the
1891 /// attached token under consideration plus child tokens under the attached
1892 /// token which are not themselves an attached token or under such a token.
1893 ///
1894 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
1895 /// first-come first-served, but a child can't logically allocate before
1896 /// all its parents have sent SetConstraints().
1897 ///
1898 /// See also SetDispensable(), which in contrast to AttachToken(), has the
1899 /// created token + children participate in constraints aggregation along
1900 /// with its parent.
1901 ///
1902 /// The newly created token needs to be Sync()ed to sysmem before the new
1903 /// token can be passed to BindSharedCollection(). The Sync() of the new
1904 /// token can be accomplished with BufferCollection.Sync() on this
1905 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
1906 /// token also works. A BufferCollectionToken.Sync() can be started after
1907 /// any BufferCollectionToken.Duplicate() messages have been sent via the
1908 /// newly created token, to also sync those additional tokens to sysmem
1909 /// using a single round-trip.
1910 ///
1911 /// These values for rights_attenuation_mask result in no attenuation (note
1912 /// that 0 is not on this list; 0 will output an ERROR to the system log
1913 /// to help diagnose the bug in client code):
1914 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
1915 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
1916 pub fn r#attach_token(
1917 &self,
1918 mut rights_attenuation_mask: u32,
1919 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
1920 ) -> Result<(), fidl::Error> {
1921 self.client.send::<BufferCollectionAttachTokenRequest>(
1922 (rights_attenuation_mask, token_request),
1923 0x6f5adcca4ac7443e,
1924 fidl::encoding::DynamicFlags::empty(),
1925 )
1926 }
1927
1928 /// AttachLifetimeTracking:
1929 ///
1930 /// AttachLifetimeTracking() is intended to allow a client to wait until an
1931 /// old logical buffer collection is fully or mostly deallocated before
1932 /// attempting allocation of a new logical buffer collection.
1933 ///
1934 /// Attach an eventpair endpoint to the logical buffer collection, so that
1935 /// the server_end will be closed when the number of buffers allocated
1936 /// drops to 'buffers_remaining'. The server_end won't close until after
1937 /// logical allocation has completed.
1938 ///
1939 /// If logical allocation fails, such as for an attached sub-tree (using
1940 /// AttachToken()), the server_end will close during that failure regardless
1941 /// of the number of buffers potenitally allocated in the overall logical
1942 /// buffer collection.
1943 ///
1944 /// The lifetime signalled by this event includes asynchronous cleanup of
1945 /// allocated buffers, and this asynchronous cleanup cannot occur until all
1946 /// holders of VMO handles to the buffers have closed those VMO handles.
1947 /// Therefore clients should take care not to become blocked forever waiting
1948 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
1949 /// participants using the logical buffer collection are less trusted or
1950 /// less reliable.
1951 ///
1952 /// The buffers_remaining parameter allows waiting for all but
1953 /// buffers_remaining buffers to be fully deallocated. This can be useful
1954 /// in situations where a known number of buffers are intentionally not
1955 /// closed so that the data can continue to be used, such as for keeping the
1956 /// last available video picture displayed in the UI even if the video
1957 /// stream was using protected output buffers. It's outside the scope of
1958 /// the BufferCollection interface (at least for now) to determine how many
1959 /// buffers may be held without closing, but it'll typically be in the range
1960 /// 0-2.
1961 ///
1962 /// This mechanism is meant to be compatible with other protocols providing
1963 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
1964 /// same event can be sent to more than one AttachLifetimeTracking(), and
1965 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
1966 /// over conditions are met (all holders of duplicates have closed their
1967 /// handle(s)).
1968 ///
1969 /// There is no way to cancel an attach. Closing the client end of the
1970 /// eventpair doesn't subtract from the number of pending attach(es).
1971 ///
1972 /// Closing the client's end doesn't result in any action by the server.
1973 /// If the server listens to events from the client end at all, it is for
1974 /// debug logging only.
1975 ///
1976 /// The server intentionally doesn't "trust" any bits signalled by the
1977 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
1978 /// which can't be triggered early, and is only triggered when all handles
1979 /// to server_end are closed. No meaning is associated with any of the
1980 /// other signal bits, and clients should functionally ignore any other
1981 /// signal bits on either end of the eventpair or its peer.
1982 ///
1983 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
1984 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
1985 /// transfer without causing CodecFactory channel failure).
1986 pub fn r#attach_lifetime_tracking(
1987 &self,
1988 mut server_end: fidl::EventPair,
1989 mut buffers_remaining: u32,
1990 ) -> Result<(), fidl::Error> {
1991 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
1992 (server_end, buffers_remaining),
1993 0x170d0f1d89d50989,
1994 fidl::encoding::DynamicFlags::empty(),
1995 )
1996 }
1997}
1998
1999#[cfg(target_os = "fuchsia")]
2000impl From<BufferCollectionSynchronousProxy> for zx::Handle {
2001 fn from(value: BufferCollectionSynchronousProxy) -> Self {
2002 value.into_channel().into()
2003 }
2004}
2005
2006#[cfg(target_os = "fuchsia")]
2007impl From<fidl::Channel> for BufferCollectionSynchronousProxy {
2008 fn from(value: fidl::Channel) -> Self {
2009 Self::new(value)
2010 }
2011}
2012
2013#[cfg(target_os = "fuchsia")]
2014impl fidl::endpoints::FromClient for BufferCollectionSynchronousProxy {
2015 type Protocol = BufferCollectionMarker;
2016
2017 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionMarker>) -> Self {
2018 Self::new(value.into_channel())
2019 }
2020}
2021
2022#[derive(Debug, Clone)]
2023pub struct BufferCollectionProxy {
2024 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
2025}
2026
2027impl fidl::endpoints::Proxy for BufferCollectionProxy {
2028 type Protocol = BufferCollectionMarker;
2029
2030 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
2031 Self::new(inner)
2032 }
2033
2034 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
2035 self.client.into_channel().map_err(|client| Self { client })
2036 }
2037
2038 fn as_channel(&self) -> &::fidl::AsyncChannel {
2039 self.client.as_channel()
2040 }
2041}
2042
2043impl BufferCollectionProxy {
2044 /// Create a new Proxy for fuchsia.sysmem/BufferCollection.
2045 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
2046 let protocol_name = <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
2047 Self { client: fidl::client::Client::new(channel, protocol_name) }
2048 }
2049
2050 /// Get a Stream of events from the remote end of the protocol.
2051 ///
2052 /// # Panics
2053 ///
2054 /// Panics if the event stream was already taken.
2055 pub fn take_event_stream(&self) -> BufferCollectionEventStream {
2056 BufferCollectionEventStream { event_receiver: self.client.take_event_receiver() }
2057 }
2058
2059 /// Ensure that previous messages, including Duplicate() messages on a
2060 /// token, collection, or group, have been received server side.
2061 ///
2062 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
2063 /// valid sysmem token risks the Sync() hanging forever. See
2064 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
2065 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
2066 /// Another way is to pass the token to BindSharedCollection(), which also
2067 /// validates the token as part of exchanging it for a BufferCollection
2068 /// channel, and BufferCollection Sync() can then be used.
2069 ///
2070 /// After a Sync(), it's then safe to send the client end of token_request
2071 /// to another participant knowing the server will recognize the token when
2072 /// it's sent into BindSharedCollection() by the other participant.
2073 ///
2074 /// Other options include waiting for each token.Duplicate() to complete
2075 /// individually (using separate call to token.Sync() after each), or
2076 /// calling Sync() on BufferCollection after the token has been turned in
2077 /// via BindSharedCollection().
2078 ///
2079 /// Another way to mitigate is to avoid calling Sync() on the token, and
2080 /// instead later deal with potential failure of BufferCollection.Sync() if
2081 /// the original token was invalid. This option can be preferable from a
2082 /// performance point of view, but requires client code to delay sending
2083 /// tokens duplicated from this token until after client code has converted
2084 /// the duplicating token to a BufferCollection and received successful
2085 /// response from BufferCollection.Sync().
2086 ///
2087 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
2088 /// When BufferCollection.Sync() isn't feasible, the caller must already
2089 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
2090 /// hang forever. See ValidateBufferCollectionToken() to check token
2091 /// validity first if the token isn't already known to be (is/was) valid.
2092 pub fn r#sync(
2093 &self,
2094 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
2095 BufferCollectionProxyInterface::r#sync(self)
2096 }
2097
2098 /// On a BufferCollectionToken channel:
2099 ///
2100 /// Normally a participant will convert a BufferCollectionToken into a
2101 /// BufferCollection view, but a participant is also free to Close() the
2102 /// token (and then close the channel immediately or shortly later in
2103 /// response to server closing its end), which avoids causing logical buffer
2104 /// collection failure. Â Normally an unexpected token channel close will
2105 /// cause logical buffer collection failure (the only exceptions being
2106 /// certain cases involving AttachToken() or SetDispensable()).
2107 ///
2108 /// On a BufferCollection channel:
2109 ///
2110 /// By default the server handles unexpected failure of a BufferCollection
2111 /// by failing the whole logical buffer collection. Partly this is to
2112 /// expedite closing VMO handles to reclaim memory when any participant
2113 /// fails. If a participant would like to cleanly close a BufferCollection
2114 /// view without causing logical buffer collection failure, the participant
2115 /// can send Close() before closing the client end of the BufferCollection
2116 /// channel. If this is the last BufferCollection view, the logical buffer
2117 /// collection will still go away. The Close() can occur before or after
2118 /// SetConstraints(). If before SetConstraints(), the buffer collection
2119 /// won't require constraints from this node in order to allocate. If
2120 /// after SetConstraints(), the constraints are retained and aggregated
2121 /// along with any subsequent logical allocation(s), despite the lack of
2122 /// channel connection.
2123 ///
2124 /// On a BufferCollectionTokenGroup channel:
2125 ///
2126 /// By default, unexpected failure of a BufferCollectionTokenGroup will
2127 /// trigger failure of the logical BufferCollectionTokenGroup and will
2128 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
2129 /// channel without failing the logical group or propagating failure, send
2130 /// Close() before closing the channel client endpoint.
2131 ///
2132 /// If Close() occurs before AllChildrenPresent(), the logical buffer
2133 /// collection will still fail despite the Close() (because sysmem can't be
2134 /// sure whether all relevant children were created, so it's ambiguous
2135 /// whether all relevant constraints will be provided to sysmem). If
2136 /// Close() occurs after AllChildrenPresent(), the children and all their
2137 /// constraints remain intact (just as they would if the
2138 /// BufferCollectionTokenGroup channel had remained open), and the close
2139 /// doesn't trigger or propagate failure.
2140 pub fn r#close(&self) -> Result<(), fidl::Error> {
2141 BufferCollectionProxyInterface::r#close(self)
2142 }
2143
2144 /// Set a name for VMOs in this buffer collection. The name may be truncated
2145 /// shorter. The name only affects VMOs allocated after it's set - this call
2146 /// does not rename existing VMOs. If multiple clients set different names
2147 /// then the larger priority value will win.
2148 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
2149 BufferCollectionProxyInterface::r#set_name(self, priority, name)
2150 }
2151
2152 /// Set information about the current client that can be used by sysmem to
2153 /// help debug leaking memory and hangs waiting for constraints. |name| can
2154 /// be an arbitrary string, but the current process name (see
2155 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
2156 /// arbitrary id, but the current process ID (see
2157 /// fsl::GetCurrentProcessKoid()) is a good default.
2158 ///
2159 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
2160 /// indicate which client is closing their channel first, leading to
2161 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
2162 /// over, but if happening earlier than expected, the
2163 /// client-channel-specific name can help diagnose where the failure is
2164 /// first coming from, from sysmem's point of view).
2165 ///
2166 /// By default (unless overriden by this message or using
2167 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
2168 /// parent Node at the time the child Node is created. While this can be
2169 /// better than nothing, it's often better for each participant to use
2170 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
2171 /// info directly relevant to the current client. Also, SetVerboseLogging()
2172 /// can be used to help disambiguate if a Node is suspected of having info
2173 /// that was copied from its parent.
2174 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
2175 BufferCollectionProxyInterface::r#set_debug_client_info(self, name, id)
2176 }
2177
2178 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
2179 /// after creating a collection. Clients can call this method to change
2180 /// when the log is printed. If multiple client set the deadline, it's
2181 /// unspecified which deadline will take effect.
2182 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
2183 BufferCollectionProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
2184 }
2185
2186 /// Verbose logging includes constraints set via SetConstraints() from each
2187 /// client along with info set via SetDebugClientInfo() and the structure of
2188 /// the tree of Node(s).
2189 ///
2190 /// Normally sysmem prints only a single line complaint when aggregation
2191 /// fails, with just the specific detailed reason that aggregation failed,
2192 /// with minimal context. While this is often enough to diagnose a problem
2193 /// if only a small change was made and the system had been working before
2194 /// the small change, it's often not particularly helpful for getting a new
2195 /// buffer collection to work for the first time. Especially with more
2196 /// complex trees of nodes, involving things like AttachToken(),
2197 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
2198 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
2199 /// looks like and why it's failing a logical allocation, or why a tree or
2200 /// sub-tree is failing sooner than expected.
2201 ///
2202 /// The intent of the extra logging is to be acceptable from a performance
2203 /// point of view, if only enabled on a low number of buffer collections.
2204 /// If we're not tracking down a bug, we shouldn't send this message.
2205 ///
2206 /// If too many participants leave verbose logging enabled, we may end up
2207 /// needing to require that system-wide sysmem verbose logging be permitted
2208 /// via some other setting, to avoid sysmem spamming the log too much due to
2209 /// this message.
2210 ///
2211 /// This may be a NOP for some nodes due to intentional policy associated
2212 /// with the node, if we don't trust a node enough to let it turn on verbose
2213 /// logging.
2214 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
2215 BufferCollectionProxyInterface::r#set_verbose_logging(self)
2216 }
2217
2218 /// This gets an event handle that can be used as a parameter to
2219 /// IsAlternateFor() called on any Node. The client will not be granted the
2220 /// right to signal this event, as this handle should only be used as proof
2221 /// that the client obtained this handle from this Node.
2222 ///
2223 /// Because this is a get not a set, no Sync() is needed between the
2224 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
2225 /// potentially being on different channels.
2226 ///
2227 /// See also IsAlternateFor().
2228 pub fn r#get_node_ref(
2229 &self,
2230 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
2231 {
2232 BufferCollectionProxyInterface::r#get_node_ref(self)
2233 }
2234
2235 /// This checks whether the calling node is in a subtree rooted at a
2236 /// different child token of a common parent BufferCollectionTokenGroup, in
2237 /// relation to the passed-in node_ref.
2238 ///
2239 /// This call is for assisting with admission control de-duplication, and
2240 /// with debugging.
2241 ///
2242 /// The node_ref must be obtained using GetNodeRef() of a
2243 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
2244 ///
2245 /// The node_ref can be a duplicated handle; it's not necessary to call
2246 /// GetNodeRef() for every call to IsAlternateFor().
2247 ///
2248 /// If a calling token may not actually be a valid token at all due to
2249 /// a potentially hostile/untrusted provider of the token, call
2250 /// ValidateBufferCollectionToken() first instead of potentially getting
2251 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
2252 /// token not being a real token (not really talking to sysmem). Another
2253 /// option is to call BindSharedCollection with this token first which also
2254 /// validates the token along with converting it to a BufferCollection, then
2255 /// call BufferCollection IsAlternateFor().
2256 ///
2257 /// error values:
2258 ///
2259 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
2260 /// buffer collection as the calling Node. Before logical allocation and
2261 /// within the same logical allocation sub-tree, this essentially means that
2262 /// the node_ref was never part of this logical buffer collection, since
2263 /// before logical allocation all node_refs that come into existence remain
2264 /// in existence at least until logical allocation (including Node(s) that
2265 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
2266 /// to be returned, this Node's channel needs to still be connected server
2267 /// side, which won't be the case if the whole logical allocation has
2268 /// failed. After logical allocation or in a different logical allocation
2269 /// sub-tree there are additional potential reasons for this error. For
2270 /// example a different logical allocation (separated from this Node(s)
2271 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
2272 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
2273 /// exist and may select a different child sub-tree than the sub-tree the
2274 /// node_ref is in causing deletion of the node_ref Node. The only time
2275 /// sysmem keeps a Node around after that Node has no corresponding channel
2276 /// is when Close() is used and the Node's sub-tree has not yet failed.
2277 /// Another reason for this error is if the node_ref is an eventpair handle
2278 /// with sufficient rights, but isn't actually a real node_ref obtained from
2279 /// GetNodeRef().
2280 ///
2281 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
2282 /// eventpair handle, or doesn't have the needed rights expected on a real
2283 /// node_ref.
2284 ///
2285 /// No other failing status codes are returned by this call. However,
2286 /// sysmem may add additional codes in future, so the client should have
2287 /// sensible default handling for any failing status code.
2288 ///
2289 /// On success, is_alternate has the following meaning:
2290 /// * true - The first parent node in common between the calling node and
2291 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
2292 /// the calling Node and the node_ref Node will _not_ have both their
2293 /// constraints apply - rather sysmem will choose one or the other of
2294 /// the constraints - never both. This is because only one child of
2295 /// a BufferCollectionTokenGroup is selected during logical allocation,
2296 /// with only that one child's sub-tree contributing to constraints
2297 /// aggregation.
2298 /// * false - The first parent node in common between the calling Node and
2299 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
2300 /// this means the first parent node in common is a
2301 /// BufferCollectionToken or BufferCollection (regardless of not
2302 /// Close()ed or Close()ed). This means that the calling Node and the
2303 /// node_ref Node _may_ have both their constraints apply during
2304 /// constraints aggregation of the logical allocation, if both Node(s)
2305 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
2306 /// In this case, there is no BufferCollectionTokenGroup that will
2307 /// directly prevent the two Node(s) from both being selected and their
2308 /// constraints both aggregated, but even when false, one or both
2309 /// Node(s) may still be eliminated from consideration if one or both
2310 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
2311 /// which selects a child sub-tree other than the sub-tree containing
2312 /// the calling Node or node_ref Node.
2313 pub fn r#is_alternate_for(
2314 &self,
2315 mut node_ref: fidl::Event,
2316 ) -> fidl::client::QueryResponseFut<
2317 NodeIsAlternateForResult,
2318 fidl::encoding::DefaultFuchsiaResourceDialect,
2319 > {
2320 BufferCollectionProxyInterface::r#is_alternate_for(self, node_ref)
2321 }
2322
2323 /// Provide BufferCollectionConstraints to the logical BufferCollection.
2324 ///
2325 /// A participant may only call SetConstraints() once.
2326 ///
2327 /// Sometimes the initiator is a participant only in the sense of wanting to
2328 /// keep an eye on success/failure to populate with buffers, and zx.Status
2329 /// on failure. In that case, `has_constraints` can be false, and
2330 /// `constraints` will be ignored.
2331 ///
2332 /// VMO handles will not be provided to the client that sends null
2333 /// constraints - that can be intentional for an initiator that doesn't need
2334 /// VMO handles. Not having VMO handles doesn't prevent the initator from
2335 /// adjusting which portion of a buffer is considered valid and similar, but
2336 /// the initiator can't hold a VMO handle open to prevent the logical
2337 /// BufferCollection from cleaning up if the logical BufferCollection needs
2338 /// to go away regardless of the initiator's degree of involvement for
2339 /// whatever reason.
2340 ///
2341 /// For population of buffers to be attempted, all holders of a
2342 /// BufferCollection client channel need to call SetConstraints() before
2343 /// sysmem will attempt to allocate buffers.
2344 ///
2345 /// `has_constraints` if false, the constraints are effectively null, and
2346 /// `constraints` are ignored. The sender of null constraints won't get any
2347 /// VMO handles in BufferCollectionInfo, but can still find out how many
2348 /// buffers were allocated and can still refer to buffers by their
2349 /// buffer_index.
2350 ///
2351 /// `constraints` are constraints on the buffer collection.
2352 pub fn r#set_constraints(
2353 &self,
2354 mut has_constraints: bool,
2355 mut constraints: &BufferCollectionConstraints,
2356 ) -> Result<(), fidl::Error> {
2357 BufferCollectionProxyInterface::r#set_constraints(self, has_constraints, constraints)
2358 }
2359
2360 /// This request completes when buffers have been allocated, responds with
2361 /// some failure detail if allocation has been attempted but failed.
2362 ///
2363 /// The following must occur before buffers will be allocated:
2364 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
2365 /// must be turned in via BindSharedCollection().
2366 /// * All BufferCollection(s) of the logical BufferCollection must have
2367 /// had SetConstraints() sent to them.
2368 ///
2369 /// Returns `ZX_OK` if successful.
2370 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
2371 /// fulfilled due to resource exhaustion.
2372 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
2373 /// obtain the buffers it requested.
2374 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
2375 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
2376 /// satisfied, perhaps due to hardware limitations.
2377 ///
2378 /// `buffer_collection_info` has the VMO handles and other related info.
2379 pub fn r#wait_for_buffers_allocated(
2380 &self,
2381 ) -> fidl::client::QueryResponseFut<
2382 (i32, BufferCollectionInfo2),
2383 fidl::encoding::DefaultFuchsiaResourceDialect,
2384 > {
2385 BufferCollectionProxyInterface::r#wait_for_buffers_allocated(self)
2386 }
2387
2388 /// This returns the same result code as WaitForBuffersAllocated if the
2389 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
2390 /// if WaitForBuffersAllocated would block.
2391 pub fn r#check_buffers_allocated(
2392 &self,
2393 ) -> fidl::client::QueryResponseFut<i32, fidl::encoding::DefaultFuchsiaResourceDialect> {
2394 BufferCollectionProxyInterface::r#check_buffers_allocated(self)
2395 }
2396
2397 /// Create a new token, for trying to add a new participant to an existing
2398 /// collection, if the existing collection's buffer counts, constraints,
2399 /// and participants allow.
2400 ///
2401 /// This can be useful in replacing a failed participant, and/or in
2402 /// adding/re-adding a participant after buffers have already been
2403 /// allocated.
2404 ///
2405 /// Failure of an attached token / collection does not propagate to the
2406 /// parent of the attached token. Failure does propagate from a normal
2407 /// child of a dispensable token to the dispensable token. Failure
2408 /// of a child is blocked from reaching its parent if the child is attached,
2409 /// or if the child is dispensable and the failure occurred after logical
2410 /// allocation.
2411 ///
2412 /// An initiator may in some scenarios choose to initially use a dispensable
2413 /// token for a given instance of a participant, and then later if the first
2414 /// instance of that participant fails, a new second instance of that
2415 /// participant my be given a token created with AttachToken().
2416 ///
2417 /// From the point of view of the client end of the BufferCollectionToken
2418 /// channel, the token acts like any other token. The client can
2419 /// Duplicate() the token as needed, and can send the token to a different
2420 /// process. The token should be converted to a BufferCollection channel
2421 /// as normal by calling BindSharedCollection(). SetConstraints() should
2422 /// be called on that BufferCollection channel.
2423 ///
2424 /// A success result from WaitForBuffersAllocated() means the new
2425 /// participant's constraints were satisfiable using the already-existing
2426 /// buffer collection, the already-established BufferCollectionInfo
2427 /// including image format constraints, and the already-existing other
2428 /// participants and their buffer counts. A failure result means the new
2429 /// participant's constraints cannot be satisfied using the existing
2430 /// buffer collection and its already-logically-allocated participants.
2431 /// Creating a new collection instead may allow all participant's
2432 /// constraints to be satisfied, assuming SetDispensable() is used in place
2433 /// of AttachToken(), or a normal token is used.
2434 ///
2435 /// A token created with AttachToken() performs constraints aggregation with
2436 /// all constraints currently in effect on the buffer collection, plus the
2437 /// attached token under consideration plus child tokens under the attached
2438 /// token which are not themselves an attached token or under such a token.
2439 ///
2440 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
2441 /// first-come first-served, but a child can't logically allocate before
2442 /// all its parents have sent SetConstraints().
2443 ///
2444 /// See also SetDispensable(), which in contrast to AttachToken(), has the
2445 /// created token + children participate in constraints aggregation along
2446 /// with its parent.
2447 ///
2448 /// The newly created token needs to be Sync()ed to sysmem before the new
2449 /// token can be passed to BindSharedCollection(). The Sync() of the new
2450 /// token can be accomplished with BufferCollection.Sync() on this
2451 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
2452 /// token also works. A BufferCollectionToken.Sync() can be started after
2453 /// any BufferCollectionToken.Duplicate() messages have been sent via the
2454 /// newly created token, to also sync those additional tokens to sysmem
2455 /// using a single round-trip.
2456 ///
2457 /// These values for rights_attenuation_mask result in no attenuation (note
2458 /// that 0 is not on this list; 0 will output an ERROR to the system log
2459 /// to help diagnose the bug in client code):
2460 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
2461 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
2462 pub fn r#attach_token(
2463 &self,
2464 mut rights_attenuation_mask: u32,
2465 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
2466 ) -> Result<(), fidl::Error> {
2467 BufferCollectionProxyInterface::r#attach_token(self, rights_attenuation_mask, token_request)
2468 }
2469
2470 /// AttachLifetimeTracking:
2471 ///
2472 /// AttachLifetimeTracking() is intended to allow a client to wait until an
2473 /// old logical buffer collection is fully or mostly deallocated before
2474 /// attempting allocation of a new logical buffer collection.
2475 ///
2476 /// Attach an eventpair endpoint to the logical buffer collection, so that
2477 /// the server_end will be closed when the number of buffers allocated
2478 /// drops to 'buffers_remaining'. The server_end won't close until after
2479 /// logical allocation has completed.
2480 ///
2481 /// If logical allocation fails, such as for an attached sub-tree (using
2482 /// AttachToken()), the server_end will close during that failure regardless
2483 /// of the number of buffers potenitally allocated in the overall logical
2484 /// buffer collection.
2485 ///
2486 /// The lifetime signalled by this event includes asynchronous cleanup of
2487 /// allocated buffers, and this asynchronous cleanup cannot occur until all
2488 /// holders of VMO handles to the buffers have closed those VMO handles.
2489 /// Therefore clients should take care not to become blocked forever waiting
2490 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
2491 /// participants using the logical buffer collection are less trusted or
2492 /// less reliable.
2493 ///
2494 /// The buffers_remaining parameter allows waiting for all but
2495 /// buffers_remaining buffers to be fully deallocated. This can be useful
2496 /// in situations where a known number of buffers are intentionally not
2497 /// closed so that the data can continue to be used, such as for keeping the
2498 /// last available video picture displayed in the UI even if the video
2499 /// stream was using protected output buffers. It's outside the scope of
2500 /// the BufferCollection interface (at least for now) to determine how many
2501 /// buffers may be held without closing, but it'll typically be in the range
2502 /// 0-2.
2503 ///
2504 /// This mechanism is meant to be compatible with other protocols providing
2505 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
2506 /// same event can be sent to more than one AttachLifetimeTracking(), and
2507 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
2508 /// over conditions are met (all holders of duplicates have closed their
2509 /// handle(s)).
2510 ///
2511 /// There is no way to cancel an attach. Closing the client end of the
2512 /// eventpair doesn't subtract from the number of pending attach(es).
2513 ///
2514 /// Closing the client's end doesn't result in any action by the server.
2515 /// If the server listens to events from the client end at all, it is for
2516 /// debug logging only.
2517 ///
2518 /// The server intentionally doesn't "trust" any bits signalled by the
2519 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
2520 /// which can't be triggered early, and is only triggered when all handles
2521 /// to server_end are closed. No meaning is associated with any of the
2522 /// other signal bits, and clients should functionally ignore any other
2523 /// signal bits on either end of the eventpair or its peer.
2524 ///
2525 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
2526 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
2527 /// transfer without causing CodecFactory channel failure).
2528 pub fn r#attach_lifetime_tracking(
2529 &self,
2530 mut server_end: fidl::EventPair,
2531 mut buffers_remaining: u32,
2532 ) -> Result<(), fidl::Error> {
2533 BufferCollectionProxyInterface::r#attach_lifetime_tracking(
2534 self,
2535 server_end,
2536 buffers_remaining,
2537 )
2538 }
2539}
2540
2541impl BufferCollectionProxyInterface for BufferCollectionProxy {
2542 type SyncResponseFut =
2543 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
2544 fn r#sync(&self) -> Self::SyncResponseFut {
2545 fn _decode(
2546 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2547 ) -> Result<(), fidl::Error> {
2548 let _response = fidl::client::decode_transaction_body::<
2549 fidl::encoding::EmptyPayload,
2550 fidl::encoding::DefaultFuchsiaResourceDialect,
2551 0x4577e238ae26291,
2552 >(_buf?)?;
2553 Ok(_response)
2554 }
2555 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
2556 (),
2557 0x4577e238ae26291,
2558 fidl::encoding::DynamicFlags::empty(),
2559 _decode,
2560 )
2561 }
2562
2563 fn r#close(&self) -> Result<(), fidl::Error> {
2564 self.client.send::<fidl::encoding::EmptyPayload>(
2565 (),
2566 0x5b1d7a4f5681fca7,
2567 fidl::encoding::DynamicFlags::empty(),
2568 )
2569 }
2570
2571 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
2572 self.client.send::<NodeSetNameRequest>(
2573 (priority, name),
2574 0x77a41bb6217e2443,
2575 fidl::encoding::DynamicFlags::empty(),
2576 )
2577 }
2578
2579 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
2580 self.client.send::<NodeSetDebugClientInfoRequest>(
2581 (name, id),
2582 0x7275759070eb5ee2,
2583 fidl::encoding::DynamicFlags::empty(),
2584 )
2585 }
2586
2587 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
2588 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
2589 (deadline,),
2590 0x46d38f4772638867,
2591 fidl::encoding::DynamicFlags::empty(),
2592 )
2593 }
2594
2595 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
2596 self.client.send::<fidl::encoding::EmptyPayload>(
2597 (),
2598 0x6bfbe2cf1701d288,
2599 fidl::encoding::DynamicFlags::empty(),
2600 )
2601 }
2602
2603 type GetNodeRefResponseFut =
2604 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
2605 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
2606 fn _decode(
2607 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2608 ) -> Result<fidl::Event, fidl::Error> {
2609 let _response = fidl::client::decode_transaction_body::<
2610 NodeGetNodeRefResponse,
2611 fidl::encoding::DefaultFuchsiaResourceDialect,
2612 0x467b7c75c35c3b84,
2613 >(_buf?)?;
2614 Ok(_response.node_ref)
2615 }
2616 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
2617 (),
2618 0x467b7c75c35c3b84,
2619 fidl::encoding::DynamicFlags::empty(),
2620 _decode,
2621 )
2622 }
2623
2624 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
2625 NodeIsAlternateForResult,
2626 fidl::encoding::DefaultFuchsiaResourceDialect,
2627 >;
2628 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
2629 fn _decode(
2630 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2631 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
2632 let _response = fidl::client::decode_transaction_body::<
2633 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
2634 fidl::encoding::DefaultFuchsiaResourceDialect,
2635 0x33a2a7aff2776c07,
2636 >(_buf?)?;
2637 Ok(_response.map(|x| x.is_alternate))
2638 }
2639 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
2640 (node_ref,),
2641 0x33a2a7aff2776c07,
2642 fidl::encoding::DynamicFlags::empty(),
2643 _decode,
2644 )
2645 }
2646
2647 fn r#set_constraints(
2648 &self,
2649 mut has_constraints: bool,
2650 mut constraints: &BufferCollectionConstraints,
2651 ) -> Result<(), fidl::Error> {
2652 self.client.send::<BufferCollectionSetConstraintsRequest>(
2653 (has_constraints, constraints),
2654 0x4d9c3406c213227b,
2655 fidl::encoding::DynamicFlags::empty(),
2656 )
2657 }
2658
2659 type WaitForBuffersAllocatedResponseFut = fidl::client::QueryResponseFut<
2660 (i32, BufferCollectionInfo2),
2661 fidl::encoding::DefaultFuchsiaResourceDialect,
2662 >;
2663 fn r#wait_for_buffers_allocated(&self) -> Self::WaitForBuffersAllocatedResponseFut {
2664 fn _decode(
2665 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2666 ) -> Result<(i32, BufferCollectionInfo2), fidl::Error> {
2667 let _response = fidl::client::decode_transaction_body::<
2668 BufferCollectionWaitForBuffersAllocatedResponse,
2669 fidl::encoding::DefaultFuchsiaResourceDialect,
2670 0x714667ea2a29a3a2,
2671 >(_buf?)?;
2672 Ok((_response.status, _response.buffer_collection_info))
2673 }
2674 self.client
2675 .send_query_and_decode::<fidl::encoding::EmptyPayload, (i32, BufferCollectionInfo2)>(
2676 (),
2677 0x714667ea2a29a3a2,
2678 fidl::encoding::DynamicFlags::empty(),
2679 _decode,
2680 )
2681 }
2682
2683 type CheckBuffersAllocatedResponseFut =
2684 fidl::client::QueryResponseFut<i32, fidl::encoding::DefaultFuchsiaResourceDialect>;
2685 fn r#check_buffers_allocated(&self) -> Self::CheckBuffersAllocatedResponseFut {
2686 fn _decode(
2687 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2688 ) -> Result<i32, fidl::Error> {
2689 let _response = fidl::client::decode_transaction_body::<
2690 BufferCollectionCheckBuffersAllocatedResponse,
2691 fidl::encoding::DefaultFuchsiaResourceDialect,
2692 0x245bb81f79189e9,
2693 >(_buf?)?;
2694 Ok(_response.status)
2695 }
2696 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, i32>(
2697 (),
2698 0x245bb81f79189e9,
2699 fidl::encoding::DynamicFlags::empty(),
2700 _decode,
2701 )
2702 }
2703
2704 fn r#attach_token(
2705 &self,
2706 mut rights_attenuation_mask: u32,
2707 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
2708 ) -> Result<(), fidl::Error> {
2709 self.client.send::<BufferCollectionAttachTokenRequest>(
2710 (rights_attenuation_mask, token_request),
2711 0x6f5adcca4ac7443e,
2712 fidl::encoding::DynamicFlags::empty(),
2713 )
2714 }
2715
2716 fn r#attach_lifetime_tracking(
2717 &self,
2718 mut server_end: fidl::EventPair,
2719 mut buffers_remaining: u32,
2720 ) -> Result<(), fidl::Error> {
2721 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
2722 (server_end, buffers_remaining),
2723 0x170d0f1d89d50989,
2724 fidl::encoding::DynamicFlags::empty(),
2725 )
2726 }
2727}
2728
2729pub struct BufferCollectionEventStream {
2730 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
2731}
2732
2733impl std::marker::Unpin for BufferCollectionEventStream {}
2734
2735impl futures::stream::FusedStream for BufferCollectionEventStream {
2736 fn is_terminated(&self) -> bool {
2737 self.event_receiver.is_terminated()
2738 }
2739}
2740
2741impl futures::Stream for BufferCollectionEventStream {
2742 type Item = Result<BufferCollectionEvent, fidl::Error>;
2743
2744 fn poll_next(
2745 mut self: std::pin::Pin<&mut Self>,
2746 cx: &mut std::task::Context<'_>,
2747 ) -> std::task::Poll<Option<Self::Item>> {
2748 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
2749 &mut self.event_receiver,
2750 cx
2751 )?) {
2752 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionEvent::decode(buf))),
2753 None => std::task::Poll::Ready(None),
2754 }
2755 }
2756}
2757
2758#[derive(Debug)]
2759pub enum BufferCollectionEvent {}
2760
2761impl BufferCollectionEvent {
2762 /// Decodes a message buffer as a [`BufferCollectionEvent`].
2763 fn decode(
2764 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
2765 ) -> Result<BufferCollectionEvent, fidl::Error> {
2766 let (bytes, _handles) = buf.split_mut();
2767 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
2768 debug_assert_eq!(tx_header.tx_id, 0);
2769 match tx_header.ordinal {
2770 _ => Err(fidl::Error::UnknownOrdinal {
2771 ordinal: tx_header.ordinal,
2772 protocol_name:
2773 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
2774 }),
2775 }
2776 }
2777}
2778
2779/// A Stream of incoming requests for fuchsia.sysmem/BufferCollection.
2780pub struct BufferCollectionRequestStream {
2781 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2782 is_terminated: bool,
2783}
2784
2785impl std::marker::Unpin for BufferCollectionRequestStream {}
2786
2787impl futures::stream::FusedStream for BufferCollectionRequestStream {
2788 fn is_terminated(&self) -> bool {
2789 self.is_terminated
2790 }
2791}
2792
2793impl fidl::endpoints::RequestStream for BufferCollectionRequestStream {
2794 type Protocol = BufferCollectionMarker;
2795 type ControlHandle = BufferCollectionControlHandle;
2796
2797 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
2798 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
2799 }
2800
2801 fn control_handle(&self) -> Self::ControlHandle {
2802 BufferCollectionControlHandle { inner: self.inner.clone() }
2803 }
2804
2805 fn into_inner(
2806 self,
2807 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
2808 {
2809 (self.inner, self.is_terminated)
2810 }
2811
2812 fn from_inner(
2813 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2814 is_terminated: bool,
2815 ) -> Self {
2816 Self { inner, is_terminated }
2817 }
2818}
2819
2820impl futures::Stream for BufferCollectionRequestStream {
2821 type Item = Result<BufferCollectionRequest, fidl::Error>;
2822
2823 fn poll_next(
2824 mut self: std::pin::Pin<&mut Self>,
2825 cx: &mut std::task::Context<'_>,
2826 ) -> std::task::Poll<Option<Self::Item>> {
2827 let this = &mut *self;
2828 if this.inner.check_shutdown(cx) {
2829 this.is_terminated = true;
2830 return std::task::Poll::Ready(None);
2831 }
2832 if this.is_terminated {
2833 panic!("polled BufferCollectionRequestStream after completion");
2834 }
2835 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
2836 |bytes, handles| {
2837 match this.inner.channel().read_etc(cx, bytes, handles) {
2838 std::task::Poll::Ready(Ok(())) => {}
2839 std::task::Poll::Pending => return std::task::Poll::Pending,
2840 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
2841 this.is_terminated = true;
2842 return std::task::Poll::Ready(None);
2843 }
2844 std::task::Poll::Ready(Err(e)) => {
2845 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
2846 e.into(),
2847 ))));
2848 }
2849 }
2850
2851 // A message has been received from the channel
2852 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
2853
2854 std::task::Poll::Ready(Some(match header.ordinal {
2855 0x4577e238ae26291 => {
2856 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2857 let mut req = fidl::new_empty!(
2858 fidl::encoding::EmptyPayload,
2859 fidl::encoding::DefaultFuchsiaResourceDialect
2860 );
2861 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2862 let control_handle =
2863 BufferCollectionControlHandle { inner: this.inner.clone() };
2864 Ok(BufferCollectionRequest::Sync {
2865 responder: BufferCollectionSyncResponder {
2866 control_handle: std::mem::ManuallyDrop::new(control_handle),
2867 tx_id: header.tx_id,
2868 },
2869 })
2870 }
2871 0x5b1d7a4f5681fca7 => {
2872 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2873 let mut req = fidl::new_empty!(
2874 fidl::encoding::EmptyPayload,
2875 fidl::encoding::DefaultFuchsiaResourceDialect
2876 );
2877 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2878 let control_handle =
2879 BufferCollectionControlHandle { inner: this.inner.clone() };
2880 Ok(BufferCollectionRequest::Close { control_handle })
2881 }
2882 0x77a41bb6217e2443 => {
2883 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2884 let mut req = fidl::new_empty!(
2885 NodeSetNameRequest,
2886 fidl::encoding::DefaultFuchsiaResourceDialect
2887 );
2888 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
2889 let control_handle =
2890 BufferCollectionControlHandle { inner: this.inner.clone() };
2891 Ok(BufferCollectionRequest::SetName {
2892 priority: req.priority,
2893 name: req.name,
2894
2895 control_handle,
2896 })
2897 }
2898 0x7275759070eb5ee2 => {
2899 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2900 let mut req = fidl::new_empty!(
2901 NodeSetDebugClientInfoRequest,
2902 fidl::encoding::DefaultFuchsiaResourceDialect
2903 );
2904 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
2905 let control_handle =
2906 BufferCollectionControlHandle { inner: this.inner.clone() };
2907 Ok(BufferCollectionRequest::SetDebugClientInfo {
2908 name: req.name,
2909 id: req.id,
2910
2911 control_handle,
2912 })
2913 }
2914 0x46d38f4772638867 => {
2915 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2916 let mut req = fidl::new_empty!(
2917 NodeSetDebugTimeoutLogDeadlineRequest,
2918 fidl::encoding::DefaultFuchsiaResourceDialect
2919 );
2920 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
2921 let control_handle =
2922 BufferCollectionControlHandle { inner: this.inner.clone() };
2923 Ok(BufferCollectionRequest::SetDebugTimeoutLogDeadline {
2924 deadline: req.deadline,
2925
2926 control_handle,
2927 })
2928 }
2929 0x6bfbe2cf1701d288 => {
2930 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2931 let mut req = fidl::new_empty!(
2932 fidl::encoding::EmptyPayload,
2933 fidl::encoding::DefaultFuchsiaResourceDialect
2934 );
2935 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2936 let control_handle =
2937 BufferCollectionControlHandle { inner: this.inner.clone() };
2938 Ok(BufferCollectionRequest::SetVerboseLogging { control_handle })
2939 }
2940 0x467b7c75c35c3b84 => {
2941 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2942 let mut req = fidl::new_empty!(
2943 fidl::encoding::EmptyPayload,
2944 fidl::encoding::DefaultFuchsiaResourceDialect
2945 );
2946 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2947 let control_handle =
2948 BufferCollectionControlHandle { inner: this.inner.clone() };
2949 Ok(BufferCollectionRequest::GetNodeRef {
2950 responder: BufferCollectionGetNodeRefResponder {
2951 control_handle: std::mem::ManuallyDrop::new(control_handle),
2952 tx_id: header.tx_id,
2953 },
2954 })
2955 }
2956 0x33a2a7aff2776c07 => {
2957 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2958 let mut req = fidl::new_empty!(
2959 NodeIsAlternateForRequest,
2960 fidl::encoding::DefaultFuchsiaResourceDialect
2961 );
2962 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
2963 let control_handle =
2964 BufferCollectionControlHandle { inner: this.inner.clone() };
2965 Ok(BufferCollectionRequest::IsAlternateFor {
2966 node_ref: req.node_ref,
2967
2968 responder: BufferCollectionIsAlternateForResponder {
2969 control_handle: std::mem::ManuallyDrop::new(control_handle),
2970 tx_id: header.tx_id,
2971 },
2972 })
2973 }
2974 0x4d9c3406c213227b => {
2975 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2976 let mut req = fidl::new_empty!(
2977 BufferCollectionSetConstraintsRequest,
2978 fidl::encoding::DefaultFuchsiaResourceDialect
2979 );
2980 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionSetConstraintsRequest>(&header, _body_bytes, handles, &mut req)?;
2981 let control_handle =
2982 BufferCollectionControlHandle { inner: this.inner.clone() };
2983 Ok(BufferCollectionRequest::SetConstraints {
2984 has_constraints: req.has_constraints,
2985 constraints: req.constraints,
2986
2987 control_handle,
2988 })
2989 }
2990 0x714667ea2a29a3a2 => {
2991 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2992 let mut req = fidl::new_empty!(
2993 fidl::encoding::EmptyPayload,
2994 fidl::encoding::DefaultFuchsiaResourceDialect
2995 );
2996 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2997 let control_handle =
2998 BufferCollectionControlHandle { inner: this.inner.clone() };
2999 Ok(BufferCollectionRequest::WaitForBuffersAllocated {
3000 responder: BufferCollectionWaitForBuffersAllocatedResponder {
3001 control_handle: std::mem::ManuallyDrop::new(control_handle),
3002 tx_id: header.tx_id,
3003 },
3004 })
3005 }
3006 0x245bb81f79189e9 => {
3007 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
3008 let mut req = fidl::new_empty!(
3009 fidl::encoding::EmptyPayload,
3010 fidl::encoding::DefaultFuchsiaResourceDialect
3011 );
3012 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
3013 let control_handle =
3014 BufferCollectionControlHandle { inner: this.inner.clone() };
3015 Ok(BufferCollectionRequest::CheckBuffersAllocated {
3016 responder: BufferCollectionCheckBuffersAllocatedResponder {
3017 control_handle: std::mem::ManuallyDrop::new(control_handle),
3018 tx_id: header.tx_id,
3019 },
3020 })
3021 }
3022 0x6f5adcca4ac7443e => {
3023 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
3024 let mut req = fidl::new_empty!(
3025 BufferCollectionAttachTokenRequest,
3026 fidl::encoding::DefaultFuchsiaResourceDialect
3027 );
3028 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachTokenRequest>(&header, _body_bytes, handles, &mut req)?;
3029 let control_handle =
3030 BufferCollectionControlHandle { inner: this.inner.clone() };
3031 Ok(BufferCollectionRequest::AttachToken {
3032 rights_attenuation_mask: req.rights_attenuation_mask,
3033 token_request: req.token_request,
3034
3035 control_handle,
3036 })
3037 }
3038 0x170d0f1d89d50989 => {
3039 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
3040 let mut req = fidl::new_empty!(
3041 BufferCollectionAttachLifetimeTrackingRequest,
3042 fidl::encoding::DefaultFuchsiaResourceDialect
3043 );
3044 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachLifetimeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
3045 let control_handle =
3046 BufferCollectionControlHandle { inner: this.inner.clone() };
3047 Ok(BufferCollectionRequest::AttachLifetimeTracking {
3048 server_end: req.server_end,
3049 buffers_remaining: req.buffers_remaining,
3050
3051 control_handle,
3052 })
3053 }
3054 _ => Err(fidl::Error::UnknownOrdinal {
3055 ordinal: header.ordinal,
3056 protocol_name:
3057 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
3058 }),
3059 }))
3060 },
3061 )
3062 }
3063}
3064
3065/// BufferCollection is a connection directly from a participant to sysmem re.
3066/// a logical BufferCollection; typically the logical BufferCollection is shared
3067/// with other participants. In other words, an instance of the BufferCollection
3068/// interface is a view of a "logical buffer collection".
3069///
3070/// This connection exists to facilitate async indication of when the logical
3071/// BufferCollection has been populated with buffers.
3072///
3073/// Also, the channel's closure by the server is an indication to the client
3074/// that the client should close all VMO handles that were obtained from the
3075/// BufferCollection ASAP.
3076///
3077/// Also, this interface may in future allow specifying constraints in other
3078/// ways, and may allow for back-and-forth negotiation of constraints to some
3079/// degree.
3080///
3081/// This interface may in future allow for more than 64 VMO handles per
3082/// BufferCollection, but currently the limit is 64.
3083///
3084/// This interface may in future allow for allocating/deallocating single
3085/// buffers.
3086///
3087/// Some initiators may wait a short duration until all old logical
3088/// BufferCollection VMO handles have closed (or until the short duration times
3089/// out) before allocating a new BufferCollection, to help control physical
3090/// memory fragmentation and avoid overlap of buffer allocation lifetimes for
3091/// the old and new collections. Collections can be large enough that it's worth
3092/// avoiding allocation overlap (in time).
3093#[derive(Debug)]
3094pub enum BufferCollectionRequest {
3095 /// Ensure that previous messages, including Duplicate() messages on a
3096 /// token, collection, or group, have been received server side.
3097 ///
3098 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
3099 /// valid sysmem token risks the Sync() hanging forever. See
3100 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
3101 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
3102 /// Another way is to pass the token to BindSharedCollection(), which also
3103 /// validates the token as part of exchanging it for a BufferCollection
3104 /// channel, and BufferCollection Sync() can then be used.
3105 ///
3106 /// After a Sync(), it's then safe to send the client end of token_request
3107 /// to another participant knowing the server will recognize the token when
3108 /// it's sent into BindSharedCollection() by the other participant.
3109 ///
3110 /// Other options include waiting for each token.Duplicate() to complete
3111 /// individually (using separate call to token.Sync() after each), or
3112 /// calling Sync() on BufferCollection after the token has been turned in
3113 /// via BindSharedCollection().
3114 ///
3115 /// Another way to mitigate is to avoid calling Sync() on the token, and
3116 /// instead later deal with potential failure of BufferCollection.Sync() if
3117 /// the original token was invalid. This option can be preferable from a
3118 /// performance point of view, but requires client code to delay sending
3119 /// tokens duplicated from this token until after client code has converted
3120 /// the duplicating token to a BufferCollection and received successful
3121 /// response from BufferCollection.Sync().
3122 ///
3123 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
3124 /// When BufferCollection.Sync() isn't feasible, the caller must already
3125 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
3126 /// hang forever. See ValidateBufferCollectionToken() to check token
3127 /// validity first if the token isn't already known to be (is/was) valid.
3128 Sync { responder: BufferCollectionSyncResponder },
3129 /// On a BufferCollectionToken channel:
3130 ///
3131 /// Normally a participant will convert a BufferCollectionToken into a
3132 /// BufferCollection view, but a participant is also free to Close() the
3133 /// token (and then close the channel immediately or shortly later in
3134 /// response to server closing its end), which avoids causing logical buffer
3135 /// collection failure. Â Normally an unexpected token channel close will
3136 /// cause logical buffer collection failure (the only exceptions being
3137 /// certain cases involving AttachToken() or SetDispensable()).
3138 ///
3139 /// On a BufferCollection channel:
3140 ///
3141 /// By default the server handles unexpected failure of a BufferCollection
3142 /// by failing the whole logical buffer collection. Partly this is to
3143 /// expedite closing VMO handles to reclaim memory when any participant
3144 /// fails. If a participant would like to cleanly close a BufferCollection
3145 /// view without causing logical buffer collection failure, the participant
3146 /// can send Close() before closing the client end of the BufferCollection
3147 /// channel. If this is the last BufferCollection view, the logical buffer
3148 /// collection will still go away. The Close() can occur before or after
3149 /// SetConstraints(). If before SetConstraints(), the buffer collection
3150 /// won't require constraints from this node in order to allocate. If
3151 /// after SetConstraints(), the constraints are retained and aggregated
3152 /// along with any subsequent logical allocation(s), despite the lack of
3153 /// channel connection.
3154 ///
3155 /// On a BufferCollectionTokenGroup channel:
3156 ///
3157 /// By default, unexpected failure of a BufferCollectionTokenGroup will
3158 /// trigger failure of the logical BufferCollectionTokenGroup and will
3159 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
3160 /// channel without failing the logical group or propagating failure, send
3161 /// Close() before closing the channel client endpoint.
3162 ///
3163 /// If Close() occurs before AllChildrenPresent(), the logical buffer
3164 /// collection will still fail despite the Close() (because sysmem can't be
3165 /// sure whether all relevant children were created, so it's ambiguous
3166 /// whether all relevant constraints will be provided to sysmem). If
3167 /// Close() occurs after AllChildrenPresent(), the children and all their
3168 /// constraints remain intact (just as they would if the
3169 /// BufferCollectionTokenGroup channel had remained open), and the close
3170 /// doesn't trigger or propagate failure.
3171 Close { control_handle: BufferCollectionControlHandle },
3172 /// Set a name for VMOs in this buffer collection. The name may be truncated
3173 /// shorter. The name only affects VMOs allocated after it's set - this call
3174 /// does not rename existing VMOs. If multiple clients set different names
3175 /// then the larger priority value will win.
3176 SetName { priority: u32, name: String, control_handle: BufferCollectionControlHandle },
3177 /// Set information about the current client that can be used by sysmem to
3178 /// help debug leaking memory and hangs waiting for constraints. |name| can
3179 /// be an arbitrary string, but the current process name (see
3180 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
3181 /// arbitrary id, but the current process ID (see
3182 /// fsl::GetCurrentProcessKoid()) is a good default.
3183 ///
3184 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
3185 /// indicate which client is closing their channel first, leading to
3186 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
3187 /// over, but if happening earlier than expected, the
3188 /// client-channel-specific name can help diagnose where the failure is
3189 /// first coming from, from sysmem's point of view).
3190 ///
3191 /// By default (unless overriden by this message or using
3192 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
3193 /// parent Node at the time the child Node is created. While this can be
3194 /// better than nothing, it's often better for each participant to use
3195 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
3196 /// info directly relevant to the current client. Also, SetVerboseLogging()
3197 /// can be used to help disambiguate if a Node is suspected of having info
3198 /// that was copied from its parent.
3199 SetDebugClientInfo { name: String, id: u64, control_handle: BufferCollectionControlHandle },
3200 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
3201 /// after creating a collection. Clients can call this method to change
3202 /// when the log is printed. If multiple client set the deadline, it's
3203 /// unspecified which deadline will take effect.
3204 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: BufferCollectionControlHandle },
3205 /// Verbose logging includes constraints set via SetConstraints() from each
3206 /// client along with info set via SetDebugClientInfo() and the structure of
3207 /// the tree of Node(s).
3208 ///
3209 /// Normally sysmem prints only a single line complaint when aggregation
3210 /// fails, with just the specific detailed reason that aggregation failed,
3211 /// with minimal context. While this is often enough to diagnose a problem
3212 /// if only a small change was made and the system had been working before
3213 /// the small change, it's often not particularly helpful for getting a new
3214 /// buffer collection to work for the first time. Especially with more
3215 /// complex trees of nodes, involving things like AttachToken(),
3216 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
3217 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
3218 /// looks like and why it's failing a logical allocation, or why a tree or
3219 /// sub-tree is failing sooner than expected.
3220 ///
3221 /// The intent of the extra logging is to be acceptable from a performance
3222 /// point of view, if only enabled on a low number of buffer collections.
3223 /// If we're not tracking down a bug, we shouldn't send this message.
3224 ///
3225 /// If too many participants leave verbose logging enabled, we may end up
3226 /// needing to require that system-wide sysmem verbose logging be permitted
3227 /// via some other setting, to avoid sysmem spamming the log too much due to
3228 /// this message.
3229 ///
3230 /// This may be a NOP for some nodes due to intentional policy associated
3231 /// with the node, if we don't trust a node enough to let it turn on verbose
3232 /// logging.
3233 SetVerboseLogging { control_handle: BufferCollectionControlHandle },
3234 /// This gets an event handle that can be used as a parameter to
3235 /// IsAlternateFor() called on any Node. The client will not be granted the
3236 /// right to signal this event, as this handle should only be used as proof
3237 /// that the client obtained this handle from this Node.
3238 ///
3239 /// Because this is a get not a set, no Sync() is needed between the
3240 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
3241 /// potentially being on different channels.
3242 ///
3243 /// See also IsAlternateFor().
3244 GetNodeRef { responder: BufferCollectionGetNodeRefResponder },
3245 /// This checks whether the calling node is in a subtree rooted at a
3246 /// different child token of a common parent BufferCollectionTokenGroup, in
3247 /// relation to the passed-in node_ref.
3248 ///
3249 /// This call is for assisting with admission control de-duplication, and
3250 /// with debugging.
3251 ///
3252 /// The node_ref must be obtained using GetNodeRef() of a
3253 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
3254 ///
3255 /// The node_ref can be a duplicated handle; it's not necessary to call
3256 /// GetNodeRef() for every call to IsAlternateFor().
3257 ///
3258 /// If a calling token may not actually be a valid token at all due to
3259 /// a potentially hostile/untrusted provider of the token, call
3260 /// ValidateBufferCollectionToken() first instead of potentially getting
3261 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
3262 /// token not being a real token (not really talking to sysmem). Another
3263 /// option is to call BindSharedCollection with this token first which also
3264 /// validates the token along with converting it to a BufferCollection, then
3265 /// call BufferCollection IsAlternateFor().
3266 ///
3267 /// error values:
3268 ///
3269 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
3270 /// buffer collection as the calling Node. Before logical allocation and
3271 /// within the same logical allocation sub-tree, this essentially means that
3272 /// the node_ref was never part of this logical buffer collection, since
3273 /// before logical allocation all node_refs that come into existence remain
3274 /// in existence at least until logical allocation (including Node(s) that
3275 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
3276 /// to be returned, this Node's channel needs to still be connected server
3277 /// side, which won't be the case if the whole logical allocation has
3278 /// failed. After logical allocation or in a different logical allocation
3279 /// sub-tree there are additional potential reasons for this error. For
3280 /// example a different logical allocation (separated from this Node(s)
3281 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
3282 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
3283 /// exist and may select a different child sub-tree than the sub-tree the
3284 /// node_ref is in causing deletion of the node_ref Node. The only time
3285 /// sysmem keeps a Node around after that Node has no corresponding channel
3286 /// is when Close() is used and the Node's sub-tree has not yet failed.
3287 /// Another reason for this error is if the node_ref is an eventpair handle
3288 /// with sufficient rights, but isn't actually a real node_ref obtained from
3289 /// GetNodeRef().
3290 ///
3291 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
3292 /// eventpair handle, or doesn't have the needed rights expected on a real
3293 /// node_ref.
3294 ///
3295 /// No other failing status codes are returned by this call. However,
3296 /// sysmem may add additional codes in future, so the client should have
3297 /// sensible default handling for any failing status code.
3298 ///
3299 /// On success, is_alternate has the following meaning:
3300 /// * true - The first parent node in common between the calling node and
3301 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
3302 /// the calling Node and the node_ref Node will _not_ have both their
3303 /// constraints apply - rather sysmem will choose one or the other of
3304 /// the constraints - never both. This is because only one child of
3305 /// a BufferCollectionTokenGroup is selected during logical allocation,
3306 /// with only that one child's sub-tree contributing to constraints
3307 /// aggregation.
3308 /// * false - The first parent node in common between the calling Node and
3309 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
3310 /// this means the first parent node in common is a
3311 /// BufferCollectionToken or BufferCollection (regardless of not
3312 /// Close()ed or Close()ed). This means that the calling Node and the
3313 /// node_ref Node _may_ have both their constraints apply during
3314 /// constraints aggregation of the logical allocation, if both Node(s)
3315 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
3316 /// In this case, there is no BufferCollectionTokenGroup that will
3317 /// directly prevent the two Node(s) from both being selected and their
3318 /// constraints both aggregated, but even when false, one or both
3319 /// Node(s) may still be eliminated from consideration if one or both
3320 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
3321 /// which selects a child sub-tree other than the sub-tree containing
3322 /// the calling Node or node_ref Node.
3323 IsAlternateFor { node_ref: fidl::Event, responder: BufferCollectionIsAlternateForResponder },
3324 /// Provide BufferCollectionConstraints to the logical BufferCollection.
3325 ///
3326 /// A participant may only call SetConstraints() once.
3327 ///
3328 /// Sometimes the initiator is a participant only in the sense of wanting to
3329 /// keep an eye on success/failure to populate with buffers, and zx.Status
3330 /// on failure. In that case, `has_constraints` can be false, and
3331 /// `constraints` will be ignored.
3332 ///
3333 /// VMO handles will not be provided to the client that sends null
3334 /// constraints - that can be intentional for an initiator that doesn't need
3335 /// VMO handles. Not having VMO handles doesn't prevent the initator from
3336 /// adjusting which portion of a buffer is considered valid and similar, but
3337 /// the initiator can't hold a VMO handle open to prevent the logical
3338 /// BufferCollection from cleaning up if the logical BufferCollection needs
3339 /// to go away regardless of the initiator's degree of involvement for
3340 /// whatever reason.
3341 ///
3342 /// For population of buffers to be attempted, all holders of a
3343 /// BufferCollection client channel need to call SetConstraints() before
3344 /// sysmem will attempt to allocate buffers.
3345 ///
3346 /// `has_constraints` if false, the constraints are effectively null, and
3347 /// `constraints` are ignored. The sender of null constraints won't get any
3348 /// VMO handles in BufferCollectionInfo, but can still find out how many
3349 /// buffers were allocated and can still refer to buffers by their
3350 /// buffer_index.
3351 ///
3352 /// `constraints` are constraints on the buffer collection.
3353 SetConstraints {
3354 has_constraints: bool,
3355 constraints: BufferCollectionConstraints,
3356 control_handle: BufferCollectionControlHandle,
3357 },
3358 /// This request completes when buffers have been allocated, responds with
3359 /// some failure detail if allocation has been attempted but failed.
3360 ///
3361 /// The following must occur before buffers will be allocated:
3362 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
3363 /// must be turned in via BindSharedCollection().
3364 /// * All BufferCollection(s) of the logical BufferCollection must have
3365 /// had SetConstraints() sent to them.
3366 ///
3367 /// Returns `ZX_OK` if successful.
3368 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
3369 /// fulfilled due to resource exhaustion.
3370 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
3371 /// obtain the buffers it requested.
3372 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
3373 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
3374 /// satisfied, perhaps due to hardware limitations.
3375 ///
3376 /// `buffer_collection_info` has the VMO handles and other related info.
3377 WaitForBuffersAllocated { responder: BufferCollectionWaitForBuffersAllocatedResponder },
3378 /// This returns the same result code as WaitForBuffersAllocated if the
3379 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
3380 /// if WaitForBuffersAllocated would block.
3381 CheckBuffersAllocated { responder: BufferCollectionCheckBuffersAllocatedResponder },
3382 /// Create a new token, for trying to add a new participant to an existing
3383 /// collection, if the existing collection's buffer counts, constraints,
3384 /// and participants allow.
3385 ///
3386 /// This can be useful in replacing a failed participant, and/or in
3387 /// adding/re-adding a participant after buffers have already been
3388 /// allocated.
3389 ///
3390 /// Failure of an attached token / collection does not propagate to the
3391 /// parent of the attached token. Failure does propagate from a normal
3392 /// child of a dispensable token to the dispensable token. Failure
3393 /// of a child is blocked from reaching its parent if the child is attached,
3394 /// or if the child is dispensable and the failure occurred after logical
3395 /// allocation.
3396 ///
3397 /// An initiator may in some scenarios choose to initially use a dispensable
3398 /// token for a given instance of a participant, and then later if the first
3399 /// instance of that participant fails, a new second instance of that
3400 /// participant my be given a token created with AttachToken().
3401 ///
3402 /// From the point of view of the client end of the BufferCollectionToken
3403 /// channel, the token acts like any other token. The client can
3404 /// Duplicate() the token as needed, and can send the token to a different
3405 /// process. The token should be converted to a BufferCollection channel
3406 /// as normal by calling BindSharedCollection(). SetConstraints() should
3407 /// be called on that BufferCollection channel.
3408 ///
3409 /// A success result from WaitForBuffersAllocated() means the new
3410 /// participant's constraints were satisfiable using the already-existing
3411 /// buffer collection, the already-established BufferCollectionInfo
3412 /// including image format constraints, and the already-existing other
3413 /// participants and their buffer counts. A failure result means the new
3414 /// participant's constraints cannot be satisfied using the existing
3415 /// buffer collection and its already-logically-allocated participants.
3416 /// Creating a new collection instead may allow all participant's
3417 /// constraints to be satisfied, assuming SetDispensable() is used in place
3418 /// of AttachToken(), or a normal token is used.
3419 ///
3420 /// A token created with AttachToken() performs constraints aggregation with
3421 /// all constraints currently in effect on the buffer collection, plus the
3422 /// attached token under consideration plus child tokens under the attached
3423 /// token which are not themselves an attached token or under such a token.
3424 ///
3425 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
3426 /// first-come first-served, but a child can't logically allocate before
3427 /// all its parents have sent SetConstraints().
3428 ///
3429 /// See also SetDispensable(), which in contrast to AttachToken(), has the
3430 /// created token + children participate in constraints aggregation along
3431 /// with its parent.
3432 ///
3433 /// The newly created token needs to be Sync()ed to sysmem before the new
3434 /// token can be passed to BindSharedCollection(). The Sync() of the new
3435 /// token can be accomplished with BufferCollection.Sync() on this
3436 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
3437 /// token also works. A BufferCollectionToken.Sync() can be started after
3438 /// any BufferCollectionToken.Duplicate() messages have been sent via the
3439 /// newly created token, to also sync those additional tokens to sysmem
3440 /// using a single round-trip.
3441 ///
3442 /// These values for rights_attenuation_mask result in no attenuation (note
3443 /// that 0 is not on this list; 0 will output an ERROR to the system log
3444 /// to help diagnose the bug in client code):
3445 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
3446 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
3447 AttachToken {
3448 rights_attenuation_mask: u32,
3449 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
3450 control_handle: BufferCollectionControlHandle,
3451 },
3452 /// AttachLifetimeTracking:
3453 ///
3454 /// AttachLifetimeTracking() is intended to allow a client to wait until an
3455 /// old logical buffer collection is fully or mostly deallocated before
3456 /// attempting allocation of a new logical buffer collection.
3457 ///
3458 /// Attach an eventpair endpoint to the logical buffer collection, so that
3459 /// the server_end will be closed when the number of buffers allocated
3460 /// drops to 'buffers_remaining'. The server_end won't close until after
3461 /// logical allocation has completed.
3462 ///
3463 /// If logical allocation fails, such as for an attached sub-tree (using
3464 /// AttachToken()), the server_end will close during that failure regardless
3465 /// of the number of buffers potenitally allocated in the overall logical
3466 /// buffer collection.
3467 ///
3468 /// The lifetime signalled by this event includes asynchronous cleanup of
3469 /// allocated buffers, and this asynchronous cleanup cannot occur until all
3470 /// holders of VMO handles to the buffers have closed those VMO handles.
3471 /// Therefore clients should take care not to become blocked forever waiting
3472 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
3473 /// participants using the logical buffer collection are less trusted or
3474 /// less reliable.
3475 ///
3476 /// The buffers_remaining parameter allows waiting for all but
3477 /// buffers_remaining buffers to be fully deallocated. This can be useful
3478 /// in situations where a known number of buffers are intentionally not
3479 /// closed so that the data can continue to be used, such as for keeping the
3480 /// last available video picture displayed in the UI even if the video
3481 /// stream was using protected output buffers. It's outside the scope of
3482 /// the BufferCollection interface (at least for now) to determine how many
3483 /// buffers may be held without closing, but it'll typically be in the range
3484 /// 0-2.
3485 ///
3486 /// This mechanism is meant to be compatible with other protocols providing
3487 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
3488 /// same event can be sent to more than one AttachLifetimeTracking(), and
3489 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
3490 /// over conditions are met (all holders of duplicates have closed their
3491 /// handle(s)).
3492 ///
3493 /// There is no way to cancel an attach. Closing the client end of the
3494 /// eventpair doesn't subtract from the number of pending attach(es).
3495 ///
3496 /// Closing the client's end doesn't result in any action by the server.
3497 /// If the server listens to events from the client end at all, it is for
3498 /// debug logging only.
3499 ///
3500 /// The server intentionally doesn't "trust" any bits signalled by the
3501 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
3502 /// which can't be triggered early, and is only triggered when all handles
3503 /// to server_end are closed. No meaning is associated with any of the
3504 /// other signal bits, and clients should functionally ignore any other
3505 /// signal bits on either end of the eventpair or its peer.
3506 ///
3507 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
3508 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
3509 /// transfer without causing CodecFactory channel failure).
3510 AttachLifetimeTracking {
3511 server_end: fidl::EventPair,
3512 buffers_remaining: u32,
3513 control_handle: BufferCollectionControlHandle,
3514 },
3515}
3516
3517impl BufferCollectionRequest {
3518 #[allow(irrefutable_let_patterns)]
3519 pub fn into_sync(self) -> Option<(BufferCollectionSyncResponder)> {
3520 if let BufferCollectionRequest::Sync { responder } = self {
3521 Some((responder))
3522 } else {
3523 None
3524 }
3525 }
3526
3527 #[allow(irrefutable_let_patterns)]
3528 pub fn into_close(self) -> Option<(BufferCollectionControlHandle)> {
3529 if let BufferCollectionRequest::Close { control_handle } = self {
3530 Some((control_handle))
3531 } else {
3532 None
3533 }
3534 }
3535
3536 #[allow(irrefutable_let_patterns)]
3537 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionControlHandle)> {
3538 if let BufferCollectionRequest::SetName { priority, name, control_handle } = self {
3539 Some((priority, name, control_handle))
3540 } else {
3541 None
3542 }
3543 }
3544
3545 #[allow(irrefutable_let_patterns)]
3546 pub fn into_set_debug_client_info(
3547 self,
3548 ) -> Option<(String, u64, BufferCollectionControlHandle)> {
3549 if let BufferCollectionRequest::SetDebugClientInfo { name, id, control_handle } = self {
3550 Some((name, id, control_handle))
3551 } else {
3552 None
3553 }
3554 }
3555
3556 #[allow(irrefutable_let_patterns)]
3557 pub fn into_set_debug_timeout_log_deadline(
3558 self,
3559 ) -> Option<(i64, BufferCollectionControlHandle)> {
3560 if let BufferCollectionRequest::SetDebugTimeoutLogDeadline { deadline, control_handle } =
3561 self
3562 {
3563 Some((deadline, control_handle))
3564 } else {
3565 None
3566 }
3567 }
3568
3569 #[allow(irrefutable_let_patterns)]
3570 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionControlHandle)> {
3571 if let BufferCollectionRequest::SetVerboseLogging { control_handle } = self {
3572 Some((control_handle))
3573 } else {
3574 None
3575 }
3576 }
3577
3578 #[allow(irrefutable_let_patterns)]
3579 pub fn into_get_node_ref(self) -> Option<(BufferCollectionGetNodeRefResponder)> {
3580 if let BufferCollectionRequest::GetNodeRef { responder } = self {
3581 Some((responder))
3582 } else {
3583 None
3584 }
3585 }
3586
3587 #[allow(irrefutable_let_patterns)]
3588 pub fn into_is_alternate_for(
3589 self,
3590 ) -> Option<(fidl::Event, BufferCollectionIsAlternateForResponder)> {
3591 if let BufferCollectionRequest::IsAlternateFor { node_ref, responder } = self {
3592 Some((node_ref, responder))
3593 } else {
3594 None
3595 }
3596 }
3597
3598 #[allow(irrefutable_let_patterns)]
3599 pub fn into_set_constraints(
3600 self,
3601 ) -> Option<(bool, BufferCollectionConstraints, BufferCollectionControlHandle)> {
3602 if let BufferCollectionRequest::SetConstraints {
3603 has_constraints,
3604 constraints,
3605 control_handle,
3606 } = self
3607 {
3608 Some((has_constraints, constraints, control_handle))
3609 } else {
3610 None
3611 }
3612 }
3613
3614 #[allow(irrefutable_let_patterns)]
3615 pub fn into_wait_for_buffers_allocated(
3616 self,
3617 ) -> Option<(BufferCollectionWaitForBuffersAllocatedResponder)> {
3618 if let BufferCollectionRequest::WaitForBuffersAllocated { responder } = self {
3619 Some((responder))
3620 } else {
3621 None
3622 }
3623 }
3624
3625 #[allow(irrefutable_let_patterns)]
3626 pub fn into_check_buffers_allocated(
3627 self,
3628 ) -> Option<(BufferCollectionCheckBuffersAllocatedResponder)> {
3629 if let BufferCollectionRequest::CheckBuffersAllocated { responder } = self {
3630 Some((responder))
3631 } else {
3632 None
3633 }
3634 }
3635
3636 #[allow(irrefutable_let_patterns)]
3637 pub fn into_attach_token(
3638 self,
3639 ) -> Option<(
3640 u32,
3641 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
3642 BufferCollectionControlHandle,
3643 )> {
3644 if let BufferCollectionRequest::AttachToken {
3645 rights_attenuation_mask,
3646 token_request,
3647 control_handle,
3648 } = self
3649 {
3650 Some((rights_attenuation_mask, token_request, control_handle))
3651 } else {
3652 None
3653 }
3654 }
3655
3656 #[allow(irrefutable_let_patterns)]
3657 pub fn into_attach_lifetime_tracking(
3658 self,
3659 ) -> Option<(fidl::EventPair, u32, BufferCollectionControlHandle)> {
3660 if let BufferCollectionRequest::AttachLifetimeTracking {
3661 server_end,
3662 buffers_remaining,
3663 control_handle,
3664 } = self
3665 {
3666 Some((server_end, buffers_remaining, control_handle))
3667 } else {
3668 None
3669 }
3670 }
3671
3672 /// Name of the method defined in FIDL
3673 pub fn method_name(&self) -> &'static str {
3674 match *self {
3675 BufferCollectionRequest::Sync { .. } => "sync",
3676 BufferCollectionRequest::Close { .. } => "close",
3677 BufferCollectionRequest::SetName { .. } => "set_name",
3678 BufferCollectionRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
3679 BufferCollectionRequest::SetDebugTimeoutLogDeadline { .. } => {
3680 "set_debug_timeout_log_deadline"
3681 }
3682 BufferCollectionRequest::SetVerboseLogging { .. } => "set_verbose_logging",
3683 BufferCollectionRequest::GetNodeRef { .. } => "get_node_ref",
3684 BufferCollectionRequest::IsAlternateFor { .. } => "is_alternate_for",
3685 BufferCollectionRequest::SetConstraints { .. } => "set_constraints",
3686 BufferCollectionRequest::WaitForBuffersAllocated { .. } => "wait_for_buffers_allocated",
3687 BufferCollectionRequest::CheckBuffersAllocated { .. } => "check_buffers_allocated",
3688 BufferCollectionRequest::AttachToken { .. } => "attach_token",
3689 BufferCollectionRequest::AttachLifetimeTracking { .. } => "attach_lifetime_tracking",
3690 }
3691 }
3692}
3693
3694#[derive(Debug, Clone)]
3695pub struct BufferCollectionControlHandle {
3696 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
3697}
3698
3699impl fidl::endpoints::ControlHandle for BufferCollectionControlHandle {
3700 fn shutdown(&self) {
3701 self.inner.shutdown()
3702 }
3703 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
3704 self.inner.shutdown_with_epitaph(status)
3705 }
3706
3707 fn is_closed(&self) -> bool {
3708 self.inner.channel().is_closed()
3709 }
3710 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
3711 self.inner.channel().on_closed()
3712 }
3713
3714 #[cfg(target_os = "fuchsia")]
3715 fn signal_peer(
3716 &self,
3717 clear_mask: zx::Signals,
3718 set_mask: zx::Signals,
3719 ) -> Result<(), zx_status::Status> {
3720 use fidl::Peered;
3721 self.inner.channel().signal_peer(clear_mask, set_mask)
3722 }
3723}
3724
3725impl BufferCollectionControlHandle {}
3726
3727#[must_use = "FIDL methods require a response to be sent"]
3728#[derive(Debug)]
3729pub struct BufferCollectionSyncResponder {
3730 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3731 tx_id: u32,
3732}
3733
3734/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3735/// if the responder is dropped without sending a response, so that the client
3736/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3737impl std::ops::Drop for BufferCollectionSyncResponder {
3738 fn drop(&mut self) {
3739 self.control_handle.shutdown();
3740 // Safety: drops once, never accessed again
3741 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3742 }
3743}
3744
3745impl fidl::endpoints::Responder for BufferCollectionSyncResponder {
3746 type ControlHandle = BufferCollectionControlHandle;
3747
3748 fn control_handle(&self) -> &BufferCollectionControlHandle {
3749 &self.control_handle
3750 }
3751
3752 fn drop_without_shutdown(mut self) {
3753 // Safety: drops once, never accessed again due to mem::forget
3754 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3755 // Prevent Drop from running (which would shut down the channel)
3756 std::mem::forget(self);
3757 }
3758}
3759
3760impl BufferCollectionSyncResponder {
3761 /// Sends a response to the FIDL transaction.
3762 ///
3763 /// Sets the channel to shutdown if an error occurs.
3764 pub fn send(self) -> Result<(), fidl::Error> {
3765 let _result = self.send_raw();
3766 if _result.is_err() {
3767 self.control_handle.shutdown();
3768 }
3769 self.drop_without_shutdown();
3770 _result
3771 }
3772
3773 /// Similar to "send" but does not shutdown the channel if an error occurs.
3774 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
3775 let _result = self.send_raw();
3776 self.drop_without_shutdown();
3777 _result
3778 }
3779
3780 fn send_raw(&self) -> Result<(), fidl::Error> {
3781 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
3782 (),
3783 self.tx_id,
3784 0x4577e238ae26291,
3785 fidl::encoding::DynamicFlags::empty(),
3786 )
3787 }
3788}
3789
3790#[must_use = "FIDL methods require a response to be sent"]
3791#[derive(Debug)]
3792pub struct BufferCollectionGetNodeRefResponder {
3793 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3794 tx_id: u32,
3795}
3796
3797/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3798/// if the responder is dropped without sending a response, so that the client
3799/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3800impl std::ops::Drop for BufferCollectionGetNodeRefResponder {
3801 fn drop(&mut self) {
3802 self.control_handle.shutdown();
3803 // Safety: drops once, never accessed again
3804 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3805 }
3806}
3807
3808impl fidl::endpoints::Responder for BufferCollectionGetNodeRefResponder {
3809 type ControlHandle = BufferCollectionControlHandle;
3810
3811 fn control_handle(&self) -> &BufferCollectionControlHandle {
3812 &self.control_handle
3813 }
3814
3815 fn drop_without_shutdown(mut self) {
3816 // Safety: drops once, never accessed again due to mem::forget
3817 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3818 // Prevent Drop from running (which would shut down the channel)
3819 std::mem::forget(self);
3820 }
3821}
3822
3823impl BufferCollectionGetNodeRefResponder {
3824 /// Sends a response to the FIDL transaction.
3825 ///
3826 /// Sets the channel to shutdown if an error occurs.
3827 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3828 let _result = self.send_raw(node_ref);
3829 if _result.is_err() {
3830 self.control_handle.shutdown();
3831 }
3832 self.drop_without_shutdown();
3833 _result
3834 }
3835
3836 /// Similar to "send" but does not shutdown the channel if an error occurs.
3837 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3838 let _result = self.send_raw(node_ref);
3839 self.drop_without_shutdown();
3840 _result
3841 }
3842
3843 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3844 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
3845 (node_ref,),
3846 self.tx_id,
3847 0x467b7c75c35c3b84,
3848 fidl::encoding::DynamicFlags::empty(),
3849 )
3850 }
3851}
3852
3853#[must_use = "FIDL methods require a response to be sent"]
3854#[derive(Debug)]
3855pub struct BufferCollectionIsAlternateForResponder {
3856 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3857 tx_id: u32,
3858}
3859
3860/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3861/// if the responder is dropped without sending a response, so that the client
3862/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3863impl std::ops::Drop for BufferCollectionIsAlternateForResponder {
3864 fn drop(&mut self) {
3865 self.control_handle.shutdown();
3866 // Safety: drops once, never accessed again
3867 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3868 }
3869}
3870
3871impl fidl::endpoints::Responder for BufferCollectionIsAlternateForResponder {
3872 type ControlHandle = BufferCollectionControlHandle;
3873
3874 fn control_handle(&self) -> &BufferCollectionControlHandle {
3875 &self.control_handle
3876 }
3877
3878 fn drop_without_shutdown(mut self) {
3879 // Safety: drops once, never accessed again due to mem::forget
3880 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3881 // Prevent Drop from running (which would shut down the channel)
3882 std::mem::forget(self);
3883 }
3884}
3885
3886impl BufferCollectionIsAlternateForResponder {
3887 /// Sends a response to the FIDL transaction.
3888 ///
3889 /// Sets the channel to shutdown if an error occurs.
3890 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
3891 let _result = self.send_raw(result);
3892 if _result.is_err() {
3893 self.control_handle.shutdown();
3894 }
3895 self.drop_without_shutdown();
3896 _result
3897 }
3898
3899 /// Similar to "send" but does not shutdown the channel if an error occurs.
3900 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
3901 let _result = self.send_raw(result);
3902 self.drop_without_shutdown();
3903 _result
3904 }
3905
3906 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
3907 self.control_handle
3908 .inner
3909 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
3910 result.map(|is_alternate| (is_alternate,)),
3911 self.tx_id,
3912 0x33a2a7aff2776c07,
3913 fidl::encoding::DynamicFlags::empty(),
3914 )
3915 }
3916}
3917
3918#[must_use = "FIDL methods require a response to be sent"]
3919#[derive(Debug)]
3920pub struct BufferCollectionWaitForBuffersAllocatedResponder {
3921 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3922 tx_id: u32,
3923}
3924
3925/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3926/// if the responder is dropped without sending a response, so that the client
3927/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3928impl std::ops::Drop for BufferCollectionWaitForBuffersAllocatedResponder {
3929 fn drop(&mut self) {
3930 self.control_handle.shutdown();
3931 // Safety: drops once, never accessed again
3932 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3933 }
3934}
3935
3936impl fidl::endpoints::Responder for BufferCollectionWaitForBuffersAllocatedResponder {
3937 type ControlHandle = BufferCollectionControlHandle;
3938
3939 fn control_handle(&self) -> &BufferCollectionControlHandle {
3940 &self.control_handle
3941 }
3942
3943 fn drop_without_shutdown(mut self) {
3944 // Safety: drops once, never accessed again due to mem::forget
3945 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3946 // Prevent Drop from running (which would shut down the channel)
3947 std::mem::forget(self);
3948 }
3949}
3950
3951impl BufferCollectionWaitForBuffersAllocatedResponder {
3952 /// Sends a response to the FIDL transaction.
3953 ///
3954 /// Sets the channel to shutdown if an error occurs.
3955 pub fn send(
3956 self,
3957 mut status: i32,
3958 mut buffer_collection_info: BufferCollectionInfo2,
3959 ) -> Result<(), fidl::Error> {
3960 let _result = self.send_raw(status, buffer_collection_info);
3961 if _result.is_err() {
3962 self.control_handle.shutdown();
3963 }
3964 self.drop_without_shutdown();
3965 _result
3966 }
3967
3968 /// Similar to "send" but does not shutdown the channel if an error occurs.
3969 pub fn send_no_shutdown_on_err(
3970 self,
3971 mut status: i32,
3972 mut buffer_collection_info: BufferCollectionInfo2,
3973 ) -> Result<(), fidl::Error> {
3974 let _result = self.send_raw(status, buffer_collection_info);
3975 self.drop_without_shutdown();
3976 _result
3977 }
3978
3979 fn send_raw(
3980 &self,
3981 mut status: i32,
3982 mut buffer_collection_info: BufferCollectionInfo2,
3983 ) -> Result<(), fidl::Error> {
3984 self.control_handle.inner.send::<BufferCollectionWaitForBuffersAllocatedResponse>(
3985 (status, &mut buffer_collection_info),
3986 self.tx_id,
3987 0x714667ea2a29a3a2,
3988 fidl::encoding::DynamicFlags::empty(),
3989 )
3990 }
3991}
3992
3993#[must_use = "FIDL methods require a response to be sent"]
3994#[derive(Debug)]
3995pub struct BufferCollectionCheckBuffersAllocatedResponder {
3996 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3997 tx_id: u32,
3998}
3999
4000/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
4001/// if the responder is dropped without sending a response, so that the client
4002/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
4003impl std::ops::Drop for BufferCollectionCheckBuffersAllocatedResponder {
4004 fn drop(&mut self) {
4005 self.control_handle.shutdown();
4006 // Safety: drops once, never accessed again
4007 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4008 }
4009}
4010
4011impl fidl::endpoints::Responder for BufferCollectionCheckBuffersAllocatedResponder {
4012 type ControlHandle = BufferCollectionControlHandle;
4013
4014 fn control_handle(&self) -> &BufferCollectionControlHandle {
4015 &self.control_handle
4016 }
4017
4018 fn drop_without_shutdown(mut self) {
4019 // Safety: drops once, never accessed again due to mem::forget
4020 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4021 // Prevent Drop from running (which would shut down the channel)
4022 std::mem::forget(self);
4023 }
4024}
4025
4026impl BufferCollectionCheckBuffersAllocatedResponder {
4027 /// Sends a response to the FIDL transaction.
4028 ///
4029 /// Sets the channel to shutdown if an error occurs.
4030 pub fn send(self, mut status: i32) -> Result<(), fidl::Error> {
4031 let _result = self.send_raw(status);
4032 if _result.is_err() {
4033 self.control_handle.shutdown();
4034 }
4035 self.drop_without_shutdown();
4036 _result
4037 }
4038
4039 /// Similar to "send" but does not shutdown the channel if an error occurs.
4040 pub fn send_no_shutdown_on_err(self, mut status: i32) -> Result<(), fidl::Error> {
4041 let _result = self.send_raw(status);
4042 self.drop_without_shutdown();
4043 _result
4044 }
4045
4046 fn send_raw(&self, mut status: i32) -> Result<(), fidl::Error> {
4047 self.control_handle.inner.send::<BufferCollectionCheckBuffersAllocatedResponse>(
4048 (status,),
4049 self.tx_id,
4050 0x245bb81f79189e9,
4051 fidl::encoding::DynamicFlags::empty(),
4052 )
4053 }
4054}
4055
4056#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
4057pub struct BufferCollectionTokenMarker;
4058
4059impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenMarker {
4060 type Proxy = BufferCollectionTokenProxy;
4061 type RequestStream = BufferCollectionTokenRequestStream;
4062 #[cfg(target_os = "fuchsia")]
4063 type SynchronousProxy = BufferCollectionTokenSynchronousProxy;
4064
4065 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionToken";
4066}
4067
4068pub trait BufferCollectionTokenProxyInterface: Send + Sync {
4069 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
4070 fn r#sync(&self) -> Self::SyncResponseFut;
4071 fn r#close(&self) -> Result<(), fidl::Error>;
4072 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
4073 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
4074 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
4075 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
4076 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
4077 + Send;
4078 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
4079 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
4080 + Send;
4081 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
4082 type DuplicateSyncResponseFut: std::future::Future<
4083 Output = Result<
4084 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
4085 fidl::Error,
4086 >,
4087 > + Send;
4088 fn r#duplicate_sync(
4089 &self,
4090 rights_attenuation_masks: &[fidl::Rights],
4091 ) -> Self::DuplicateSyncResponseFut;
4092 fn r#duplicate(
4093 &self,
4094 rights_attenuation_mask: u32,
4095 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
4096 ) -> Result<(), fidl::Error>;
4097 fn r#set_dispensable(&self) -> Result<(), fidl::Error>;
4098 fn r#create_buffer_collection_token_group(
4099 &self,
4100 group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
4101 ) -> Result<(), fidl::Error>;
4102}
4103#[derive(Debug)]
4104#[cfg(target_os = "fuchsia")]
4105pub struct BufferCollectionTokenSynchronousProxy {
4106 client: fidl::client::sync::Client,
4107}
4108
4109#[cfg(target_os = "fuchsia")]
4110impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenSynchronousProxy {
4111 type Proxy = BufferCollectionTokenProxy;
4112 type Protocol = BufferCollectionTokenMarker;
4113
4114 fn from_channel(inner: fidl::Channel) -> Self {
4115 Self::new(inner)
4116 }
4117
4118 fn into_channel(self) -> fidl::Channel {
4119 self.client.into_channel()
4120 }
4121
4122 fn as_channel(&self) -> &fidl::Channel {
4123 self.client.as_channel()
4124 }
4125}
4126
4127#[cfg(target_os = "fuchsia")]
4128impl BufferCollectionTokenSynchronousProxy {
4129 pub fn new(channel: fidl::Channel) -> Self {
4130 let protocol_name =
4131 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
4132 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
4133 }
4134
4135 pub fn into_channel(self) -> fidl::Channel {
4136 self.client.into_channel()
4137 }
4138
4139 /// Waits until an event arrives and returns it. It is safe for other
4140 /// threads to make concurrent requests while waiting for an event.
4141 pub fn wait_for_event(
4142 &self,
4143 deadline: zx::MonotonicInstant,
4144 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
4145 BufferCollectionTokenEvent::decode(self.client.wait_for_event(deadline)?)
4146 }
4147
4148 /// Ensure that previous messages, including Duplicate() messages on a
4149 /// token, collection, or group, have been received server side.
4150 ///
4151 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
4152 /// valid sysmem token risks the Sync() hanging forever. See
4153 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
4154 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
4155 /// Another way is to pass the token to BindSharedCollection(), which also
4156 /// validates the token as part of exchanging it for a BufferCollection
4157 /// channel, and BufferCollection Sync() can then be used.
4158 ///
4159 /// After a Sync(), it's then safe to send the client end of token_request
4160 /// to another participant knowing the server will recognize the token when
4161 /// it's sent into BindSharedCollection() by the other participant.
4162 ///
4163 /// Other options include waiting for each token.Duplicate() to complete
4164 /// individually (using separate call to token.Sync() after each), or
4165 /// calling Sync() on BufferCollection after the token has been turned in
4166 /// via BindSharedCollection().
4167 ///
4168 /// Another way to mitigate is to avoid calling Sync() on the token, and
4169 /// instead later deal with potential failure of BufferCollection.Sync() if
4170 /// the original token was invalid. This option can be preferable from a
4171 /// performance point of view, but requires client code to delay sending
4172 /// tokens duplicated from this token until after client code has converted
4173 /// the duplicating token to a BufferCollection and received successful
4174 /// response from BufferCollection.Sync().
4175 ///
4176 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
4177 /// When BufferCollection.Sync() isn't feasible, the caller must already
4178 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
4179 /// hang forever. See ValidateBufferCollectionToken() to check token
4180 /// validity first if the token isn't already known to be (is/was) valid.
4181 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
4182 let _response =
4183 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
4184 (),
4185 0x4577e238ae26291,
4186 fidl::encoding::DynamicFlags::empty(),
4187 ___deadline,
4188 )?;
4189 Ok(_response)
4190 }
4191
4192 /// On a BufferCollectionToken channel:
4193 ///
4194 /// Normally a participant will convert a BufferCollectionToken into a
4195 /// BufferCollection view, but a participant is also free to Close() the
4196 /// token (and then close the channel immediately or shortly later in
4197 /// response to server closing its end), which avoids causing logical buffer
4198 /// collection failure. Â Normally an unexpected token channel close will
4199 /// cause logical buffer collection failure (the only exceptions being
4200 /// certain cases involving AttachToken() or SetDispensable()).
4201 ///
4202 /// On a BufferCollection channel:
4203 ///
4204 /// By default the server handles unexpected failure of a BufferCollection
4205 /// by failing the whole logical buffer collection. Partly this is to
4206 /// expedite closing VMO handles to reclaim memory when any participant
4207 /// fails. If a participant would like to cleanly close a BufferCollection
4208 /// view without causing logical buffer collection failure, the participant
4209 /// can send Close() before closing the client end of the BufferCollection
4210 /// channel. If this is the last BufferCollection view, the logical buffer
4211 /// collection will still go away. The Close() can occur before or after
4212 /// SetConstraints(). If before SetConstraints(), the buffer collection
4213 /// won't require constraints from this node in order to allocate. If
4214 /// after SetConstraints(), the constraints are retained and aggregated
4215 /// along with any subsequent logical allocation(s), despite the lack of
4216 /// channel connection.
4217 ///
4218 /// On a BufferCollectionTokenGroup channel:
4219 ///
4220 /// By default, unexpected failure of a BufferCollectionTokenGroup will
4221 /// trigger failure of the logical BufferCollectionTokenGroup and will
4222 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
4223 /// channel without failing the logical group or propagating failure, send
4224 /// Close() before closing the channel client endpoint.
4225 ///
4226 /// If Close() occurs before AllChildrenPresent(), the logical buffer
4227 /// collection will still fail despite the Close() (because sysmem can't be
4228 /// sure whether all relevant children were created, so it's ambiguous
4229 /// whether all relevant constraints will be provided to sysmem). If
4230 /// Close() occurs after AllChildrenPresent(), the children and all their
4231 /// constraints remain intact (just as they would if the
4232 /// BufferCollectionTokenGroup channel had remained open), and the close
4233 /// doesn't trigger or propagate failure.
4234 pub fn r#close(&self) -> Result<(), fidl::Error> {
4235 self.client.send::<fidl::encoding::EmptyPayload>(
4236 (),
4237 0x5b1d7a4f5681fca7,
4238 fidl::encoding::DynamicFlags::empty(),
4239 )
4240 }
4241
4242 /// Set a name for VMOs in this buffer collection. The name may be truncated
4243 /// shorter. The name only affects VMOs allocated after it's set - this call
4244 /// does not rename existing VMOs. If multiple clients set different names
4245 /// then the larger priority value will win.
4246 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
4247 self.client.send::<NodeSetNameRequest>(
4248 (priority, name),
4249 0x77a41bb6217e2443,
4250 fidl::encoding::DynamicFlags::empty(),
4251 )
4252 }
4253
4254 /// Set information about the current client that can be used by sysmem to
4255 /// help debug leaking memory and hangs waiting for constraints. |name| can
4256 /// be an arbitrary string, but the current process name (see
4257 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
4258 /// arbitrary id, but the current process ID (see
4259 /// fsl::GetCurrentProcessKoid()) is a good default.
4260 ///
4261 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
4262 /// indicate which client is closing their channel first, leading to
4263 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
4264 /// over, but if happening earlier than expected, the
4265 /// client-channel-specific name can help diagnose where the failure is
4266 /// first coming from, from sysmem's point of view).
4267 ///
4268 /// By default (unless overriden by this message or using
4269 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
4270 /// parent Node at the time the child Node is created. While this can be
4271 /// better than nothing, it's often better for each participant to use
4272 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
4273 /// info directly relevant to the current client. Also, SetVerboseLogging()
4274 /// can be used to help disambiguate if a Node is suspected of having info
4275 /// that was copied from its parent.
4276 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
4277 self.client.send::<NodeSetDebugClientInfoRequest>(
4278 (name, id),
4279 0x7275759070eb5ee2,
4280 fidl::encoding::DynamicFlags::empty(),
4281 )
4282 }
4283
4284 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
4285 /// after creating a collection. Clients can call this method to change
4286 /// when the log is printed. If multiple client set the deadline, it's
4287 /// unspecified which deadline will take effect.
4288 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
4289 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
4290 (deadline,),
4291 0x46d38f4772638867,
4292 fidl::encoding::DynamicFlags::empty(),
4293 )
4294 }
4295
4296 /// Verbose logging includes constraints set via SetConstraints() from each
4297 /// client along with info set via SetDebugClientInfo() and the structure of
4298 /// the tree of Node(s).
4299 ///
4300 /// Normally sysmem prints only a single line complaint when aggregation
4301 /// fails, with just the specific detailed reason that aggregation failed,
4302 /// with minimal context. While this is often enough to diagnose a problem
4303 /// if only a small change was made and the system had been working before
4304 /// the small change, it's often not particularly helpful for getting a new
4305 /// buffer collection to work for the first time. Especially with more
4306 /// complex trees of nodes, involving things like AttachToken(),
4307 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
4308 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
4309 /// looks like and why it's failing a logical allocation, or why a tree or
4310 /// sub-tree is failing sooner than expected.
4311 ///
4312 /// The intent of the extra logging is to be acceptable from a performance
4313 /// point of view, if only enabled on a low number of buffer collections.
4314 /// If we're not tracking down a bug, we shouldn't send this message.
4315 ///
4316 /// If too many participants leave verbose logging enabled, we may end up
4317 /// needing to require that system-wide sysmem verbose logging be permitted
4318 /// via some other setting, to avoid sysmem spamming the log too much due to
4319 /// this message.
4320 ///
4321 /// This may be a NOP for some nodes due to intentional policy associated
4322 /// with the node, if we don't trust a node enough to let it turn on verbose
4323 /// logging.
4324 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
4325 self.client.send::<fidl::encoding::EmptyPayload>(
4326 (),
4327 0x6bfbe2cf1701d288,
4328 fidl::encoding::DynamicFlags::empty(),
4329 )
4330 }
4331
4332 /// This gets an event handle that can be used as a parameter to
4333 /// IsAlternateFor() called on any Node. The client will not be granted the
4334 /// right to signal this event, as this handle should only be used as proof
4335 /// that the client obtained this handle from this Node.
4336 ///
4337 /// Because this is a get not a set, no Sync() is needed between the
4338 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
4339 /// potentially being on different channels.
4340 ///
4341 /// See also IsAlternateFor().
4342 pub fn r#get_node_ref(
4343 &self,
4344 ___deadline: zx::MonotonicInstant,
4345 ) -> Result<fidl::Event, fidl::Error> {
4346 let _response =
4347 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
4348 (),
4349 0x467b7c75c35c3b84,
4350 fidl::encoding::DynamicFlags::empty(),
4351 ___deadline,
4352 )?;
4353 Ok(_response.node_ref)
4354 }
4355
4356 /// This checks whether the calling node is in a subtree rooted at a
4357 /// different child token of a common parent BufferCollectionTokenGroup, in
4358 /// relation to the passed-in node_ref.
4359 ///
4360 /// This call is for assisting with admission control de-duplication, and
4361 /// with debugging.
4362 ///
4363 /// The node_ref must be obtained using GetNodeRef() of a
4364 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
4365 ///
4366 /// The node_ref can be a duplicated handle; it's not necessary to call
4367 /// GetNodeRef() for every call to IsAlternateFor().
4368 ///
4369 /// If a calling token may not actually be a valid token at all due to
4370 /// a potentially hostile/untrusted provider of the token, call
4371 /// ValidateBufferCollectionToken() first instead of potentially getting
4372 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
4373 /// token not being a real token (not really talking to sysmem). Another
4374 /// option is to call BindSharedCollection with this token first which also
4375 /// validates the token along with converting it to a BufferCollection, then
4376 /// call BufferCollection IsAlternateFor().
4377 ///
4378 /// error values:
4379 ///
4380 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
4381 /// buffer collection as the calling Node. Before logical allocation and
4382 /// within the same logical allocation sub-tree, this essentially means that
4383 /// the node_ref was never part of this logical buffer collection, since
4384 /// before logical allocation all node_refs that come into existence remain
4385 /// in existence at least until logical allocation (including Node(s) that
4386 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
4387 /// to be returned, this Node's channel needs to still be connected server
4388 /// side, which won't be the case if the whole logical allocation has
4389 /// failed. After logical allocation or in a different logical allocation
4390 /// sub-tree there are additional potential reasons for this error. For
4391 /// example a different logical allocation (separated from this Node(s)
4392 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
4393 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
4394 /// exist and may select a different child sub-tree than the sub-tree the
4395 /// node_ref is in causing deletion of the node_ref Node. The only time
4396 /// sysmem keeps a Node around after that Node has no corresponding channel
4397 /// is when Close() is used and the Node's sub-tree has not yet failed.
4398 /// Another reason for this error is if the node_ref is an eventpair handle
4399 /// with sufficient rights, but isn't actually a real node_ref obtained from
4400 /// GetNodeRef().
4401 ///
4402 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
4403 /// eventpair handle, or doesn't have the needed rights expected on a real
4404 /// node_ref.
4405 ///
4406 /// No other failing status codes are returned by this call. However,
4407 /// sysmem may add additional codes in future, so the client should have
4408 /// sensible default handling for any failing status code.
4409 ///
4410 /// On success, is_alternate has the following meaning:
4411 /// * true - The first parent node in common between the calling node and
4412 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
4413 /// the calling Node and the node_ref Node will _not_ have both their
4414 /// constraints apply - rather sysmem will choose one or the other of
4415 /// the constraints - never both. This is because only one child of
4416 /// a BufferCollectionTokenGroup is selected during logical allocation,
4417 /// with only that one child's sub-tree contributing to constraints
4418 /// aggregation.
4419 /// * false - The first parent node in common between the calling Node and
4420 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
4421 /// this means the first parent node in common is a
4422 /// BufferCollectionToken or BufferCollection (regardless of not
4423 /// Close()ed or Close()ed). This means that the calling Node and the
4424 /// node_ref Node _may_ have both their constraints apply during
4425 /// constraints aggregation of the logical allocation, if both Node(s)
4426 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
4427 /// In this case, there is no BufferCollectionTokenGroup that will
4428 /// directly prevent the two Node(s) from both being selected and their
4429 /// constraints both aggregated, but even when false, one or both
4430 /// Node(s) may still be eliminated from consideration if one or both
4431 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
4432 /// which selects a child sub-tree other than the sub-tree containing
4433 /// the calling Node or node_ref Node.
4434 pub fn r#is_alternate_for(
4435 &self,
4436 mut node_ref: fidl::Event,
4437 ___deadline: zx::MonotonicInstant,
4438 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
4439 let _response = self.client.send_query::<
4440 NodeIsAlternateForRequest,
4441 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
4442 >(
4443 (node_ref,),
4444 0x33a2a7aff2776c07,
4445 fidl::encoding::DynamicFlags::empty(),
4446 ___deadline,
4447 )?;
4448 Ok(_response.map(|x| x.is_alternate))
4449 }
4450
4451 /// This method can be used to add more participants prior to creating a
4452 /// shared BufferCollection. A new token will be returned for each entry in
4453 /// the `rights_attenuation_masks` array. The return value is the client
4454 /// ends of each new participant token.
4455 ///
4456 /// If the calling token may not actually be a valid token at all due to
4457 /// a potentially hostile/untrusted provider of the token, consider using
4458 /// ValidateBufferCollectionToken() first instead of potentially getting
4459 /// stuck indefinitely if DuplicateSync() never responds due to the calling
4460 /// token not being a real token.
4461 ///
4462 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
4463 /// after calling this method.
4464 ///
4465 /// All tokens must be turned in via BindSharedCollection() or Close() for a
4466 /// BufferCollection to be successfully created.
4467 ///
4468 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
4469 /// will be absent in the buffer VMO rights obtainable via the corresponding
4470 /// returned token. This allows an initiator or intermediary participant to
4471 /// attenuate the rights available to a participant. This does not allow a
4472 /// participant to gain rights that the participant doesn't already have.
4473 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
4474 /// attenuation should be applied.
4475 pub fn r#duplicate_sync(
4476 &self,
4477 mut rights_attenuation_masks: &[fidl::Rights],
4478 ___deadline: zx::MonotonicInstant,
4479 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error> {
4480 let _response = self.client.send_query::<
4481 BufferCollectionTokenDuplicateSyncRequest,
4482 BufferCollectionTokenDuplicateSyncResponse,
4483 >(
4484 (rights_attenuation_masks,),
4485 0x49ed7ab7cc19f18,
4486 fidl::encoding::DynamicFlags::empty(),
4487 ___deadline,
4488 )?;
4489 Ok(_response.tokens)
4490 }
4491
4492 /// This method can be used to add a participant prior to creating a shared
4493 /// BufferCollection. It should only be used instead of DuplicateSync in
4494 /// performance sensitive cases where it would be undesireable to wait for
4495 /// sysmem to respond as part of each duplicate.
4496 ///
4497 /// After sending one or more Duplicate() messages, and before sending the
4498 /// created tokens to other participants (or to other Allocator channels),
4499 /// the client should send a Sync() and wait for its response. The Sync()
4500 /// call can be made on the token, or on the BufferCollection obtained by
4501 /// passing this token to BindSharedCollection(). Either will ensure that
4502 /// the server knows about the tokens created via Duplicate() before the
4503 /// other participant sends the token to the server via separate Allocator
4504 /// channel.
4505 ///
4506 /// All tokens must be turned in via BindSharedCollection() or Close() for a
4507 /// BufferCollection to be successfully created.
4508 ///
4509 /// When a client calls BindSharedCollection() to turn in a
4510 /// BufferCollectionToken, the server will process all Duplicate() messages
4511 /// before closing down the BufferCollectionToken. This allows the client
4512 /// to Duplicate() and immediately turn in the BufferCollectionToken using
4513 /// BindSharedCollection, then later transfer the client end of token_request
4514 /// to another participant - the server will notice the existence of the
4515 /// token_request before considering this BufferCollectionToken fully closed.
4516 ///
4517 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
4518 /// absent in the buffer VMO rights obtainable via the client end of
4519 /// token_request. This allows an initiator or intermediary participant to
4520 /// attenuate the rights available to a participant. This does not allow a
4521 /// participant to gain rights that the participant doesn't already have.
4522 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
4523 /// attenuation should be applied.
4524 ///
4525 /// These values for rights_attenuation_mask result in no attenuation:
4526 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
4527 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
4528 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
4529 ///
4530 /// `token_request` is the server end of a BufferCollectionToken channel.
4531 /// The client end of this channel acts as another participant in creating the
4532 /// shared BufferCollection.
4533 pub fn r#duplicate(
4534 &self,
4535 mut rights_attenuation_mask: u32,
4536 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
4537 ) -> Result<(), fidl::Error> {
4538 self.client.send::<BufferCollectionTokenDuplicateRequest>(
4539 (rights_attenuation_mask, token_request),
4540 0x2f9f81bdde4b7292,
4541 fidl::encoding::DynamicFlags::empty(),
4542 )
4543 }
4544
4545 /// A dispensable token can fail after buffers are logically allocated
4546 /// without causing failure of its parent (if any).
4547 ///
4548 /// The dispensable token participates in constraints aggregation along with
4549 /// its parent before logical buffer allocation. If the dispensable token
4550 /// fails before buffers are logically allocated, the failure propagates to
4551 /// the dispensable token's parent.
4552 ///
4553 /// After buffers are logically allocated, failure of the dispensable token
4554 /// (or any child of the dispensable token) does not propagate to the
4555 /// dispensable token's parent. Failure does propagate from a normal
4556 /// child of a dispensable token to the dispensable token. Failure
4557 /// of a child is blocked from reaching its parent if the child is attached,
4558 /// or if the child is dispensable and the failure occurred after logical
4559 /// allocation.
4560 ///
4561 /// A dispensable token can be used in cases where a participant needs to
4562 /// provide constraints, but after buffers are allocated, the participant
4563 /// can fail without causing buffer collection failure from the parent's
4564 /// point of view.
4565 ///
4566 /// In contrast, AttachToken() can be used to create a token which does not
4567 /// participate in constraints aggregation with its parent, and whose
4568 /// failure at any time does not propagate to its parent, and whose delay
4569 /// providing constraints does not prevent the parent from completing its
4570 /// buffer allocation.
4571 ///
4572 /// An initiator may in some scenarios choose to initially use a dispensable
4573 /// token for a given instance of a participant, and then later if the first
4574 /// instance of that participant fails, a new second instance of that
4575 /// participant my be given a token created with AttachToken().
4576 ///
4577 /// If a client uses this message, the client should not rely on the
4578 /// client's own BufferCollectionToken or BufferCollection channel to close
4579 /// from the server end due to abrupt failure of any BufferCollectionToken
4580 /// or BufferCollection that the client has SetDispensable() and given out
4581 /// to another process. For this reason, the client should take extra care
4582 /// to notice failure of that other process via other means.
4583 ///
4584 /// While it is possible (and potentially useful) to SetDispensable() on a
4585 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
4586 /// replace a failed dispensable token that was a direct child of a group
4587 /// with a new token using AttachToken() (since there's no AttachToken() on
4588 /// a group). Instead, to enable AttachToken() replacement in this case,
4589 /// create an additional non-dispensable token (node) that's a direct child
4590 /// of the group and make the existing dispensable token a child of the
4591 /// additional token (node). This way, the additional token (node) that is
4592 /// a direct child of the group has BufferCollection.AttachToken() which can
4593 /// be used to replace the failed dispensable token.
4594 ///
4595 /// SetDispensable() on an already-dispensable token is idempotent.
4596 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
4597 self.client.send::<fidl::encoding::EmptyPayload>(
4598 (),
4599 0x76e4ec34fc2cf5b3,
4600 fidl::encoding::DynamicFlags::empty(),
4601 )
4602 }
4603
4604 /// Most sysmem clients and many participants don't need to care about this
4605 /// message or about BufferCollectionTokenGroup(s) in general.
4606 ///
4607 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
4608 /// tokens. The child tokens which are not selected during aggregation will
4609 /// fail (close), which a potential participant should notice when their
4610 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
4611 /// participant to clean up the speculative usage that didn't end up
4612 /// happening (similarly to a normal BufferCollection server end closing
4613 /// on failure of a logical buffer collection).
4614 ///
4615 /// See comments on protocol BufferCollectionTokenGroup.
4616 ///
4617 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
4618 /// applied to the whole group can be achieved with a token for this purpose
4619 /// as a direct parent of the group.
4620 ///
4621 /// group_request - the server end of a BufferCollectionTokenGroup channel
4622 /// to be served by sysmem.
4623 pub fn r#create_buffer_collection_token_group(
4624 &self,
4625 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
4626 ) -> Result<(), fidl::Error> {
4627 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
4628 (group_request,),
4629 0x2f6243e05f22b9a7,
4630 fidl::encoding::DynamicFlags::empty(),
4631 )
4632 }
4633}
4634
4635#[cfg(target_os = "fuchsia")]
4636impl From<BufferCollectionTokenSynchronousProxy> for zx::Handle {
4637 fn from(value: BufferCollectionTokenSynchronousProxy) -> Self {
4638 value.into_channel().into()
4639 }
4640}
4641
4642#[cfg(target_os = "fuchsia")]
4643impl From<fidl::Channel> for BufferCollectionTokenSynchronousProxy {
4644 fn from(value: fidl::Channel) -> Self {
4645 Self::new(value)
4646 }
4647}
4648
4649#[cfg(target_os = "fuchsia")]
4650impl fidl::endpoints::FromClient for BufferCollectionTokenSynchronousProxy {
4651 type Protocol = BufferCollectionTokenMarker;
4652
4653 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>) -> Self {
4654 Self::new(value.into_channel())
4655 }
4656}
4657
4658#[derive(Debug, Clone)]
4659pub struct BufferCollectionTokenProxy {
4660 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
4661}
4662
4663impl fidl::endpoints::Proxy for BufferCollectionTokenProxy {
4664 type Protocol = BufferCollectionTokenMarker;
4665
4666 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
4667 Self::new(inner)
4668 }
4669
4670 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
4671 self.client.into_channel().map_err(|client| Self { client })
4672 }
4673
4674 fn as_channel(&self) -> &::fidl::AsyncChannel {
4675 self.client.as_channel()
4676 }
4677}
4678
4679impl BufferCollectionTokenProxy {
4680 /// Create a new Proxy for fuchsia.sysmem/BufferCollectionToken.
4681 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
4682 let protocol_name =
4683 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
4684 Self { client: fidl::client::Client::new(channel, protocol_name) }
4685 }
4686
4687 /// Get a Stream of events from the remote end of the protocol.
4688 ///
4689 /// # Panics
4690 ///
4691 /// Panics if the event stream was already taken.
4692 pub fn take_event_stream(&self) -> BufferCollectionTokenEventStream {
4693 BufferCollectionTokenEventStream { event_receiver: self.client.take_event_receiver() }
4694 }
4695
4696 /// Ensure that previous messages, including Duplicate() messages on a
4697 /// token, collection, or group, have been received server side.
4698 ///
4699 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
4700 /// valid sysmem token risks the Sync() hanging forever. See
4701 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
4702 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
4703 /// Another way is to pass the token to BindSharedCollection(), which also
4704 /// validates the token as part of exchanging it for a BufferCollection
4705 /// channel, and BufferCollection Sync() can then be used.
4706 ///
4707 /// After a Sync(), it's then safe to send the client end of token_request
4708 /// to another participant knowing the server will recognize the token when
4709 /// it's sent into BindSharedCollection() by the other participant.
4710 ///
4711 /// Other options include waiting for each token.Duplicate() to complete
4712 /// individually (using separate call to token.Sync() after each), or
4713 /// calling Sync() on BufferCollection after the token has been turned in
4714 /// via BindSharedCollection().
4715 ///
4716 /// Another way to mitigate is to avoid calling Sync() on the token, and
4717 /// instead later deal with potential failure of BufferCollection.Sync() if
4718 /// the original token was invalid. This option can be preferable from a
4719 /// performance point of view, but requires client code to delay sending
4720 /// tokens duplicated from this token until after client code has converted
4721 /// the duplicating token to a BufferCollection and received successful
4722 /// response from BufferCollection.Sync().
4723 ///
4724 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
4725 /// When BufferCollection.Sync() isn't feasible, the caller must already
4726 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
4727 /// hang forever. See ValidateBufferCollectionToken() to check token
4728 /// validity first if the token isn't already known to be (is/was) valid.
4729 pub fn r#sync(
4730 &self,
4731 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
4732 BufferCollectionTokenProxyInterface::r#sync(self)
4733 }
4734
4735 /// On a BufferCollectionToken channel:
4736 ///
4737 /// Normally a participant will convert a BufferCollectionToken into a
4738 /// BufferCollection view, but a participant is also free to Close() the
4739 /// token (and then close the channel immediately or shortly later in
4740 /// response to server closing its end), which avoids causing logical buffer
4741 /// collection failure. Â Normally an unexpected token channel close will
4742 /// cause logical buffer collection failure (the only exceptions being
4743 /// certain cases involving AttachToken() or SetDispensable()).
4744 ///
4745 /// On a BufferCollection channel:
4746 ///
4747 /// By default the server handles unexpected failure of a BufferCollection
4748 /// by failing the whole logical buffer collection. Partly this is to
4749 /// expedite closing VMO handles to reclaim memory when any participant
4750 /// fails. If a participant would like to cleanly close a BufferCollection
4751 /// view without causing logical buffer collection failure, the participant
4752 /// can send Close() before closing the client end of the BufferCollection
4753 /// channel. If this is the last BufferCollection view, the logical buffer
4754 /// collection will still go away. The Close() can occur before or after
4755 /// SetConstraints(). If before SetConstraints(), the buffer collection
4756 /// won't require constraints from this node in order to allocate. If
4757 /// after SetConstraints(), the constraints are retained and aggregated
4758 /// along with any subsequent logical allocation(s), despite the lack of
4759 /// channel connection.
4760 ///
4761 /// On a BufferCollectionTokenGroup channel:
4762 ///
4763 /// By default, unexpected failure of a BufferCollectionTokenGroup will
4764 /// trigger failure of the logical BufferCollectionTokenGroup and will
4765 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
4766 /// channel without failing the logical group or propagating failure, send
4767 /// Close() before closing the channel client endpoint.
4768 ///
4769 /// If Close() occurs before AllChildrenPresent(), the logical buffer
4770 /// collection will still fail despite the Close() (because sysmem can't be
4771 /// sure whether all relevant children were created, so it's ambiguous
4772 /// whether all relevant constraints will be provided to sysmem). If
4773 /// Close() occurs after AllChildrenPresent(), the children and all their
4774 /// constraints remain intact (just as they would if the
4775 /// BufferCollectionTokenGroup channel had remained open), and the close
4776 /// doesn't trigger or propagate failure.
4777 pub fn r#close(&self) -> Result<(), fidl::Error> {
4778 BufferCollectionTokenProxyInterface::r#close(self)
4779 }
4780
4781 /// Set a name for VMOs in this buffer collection. The name may be truncated
4782 /// shorter. The name only affects VMOs allocated after it's set - this call
4783 /// does not rename existing VMOs. If multiple clients set different names
4784 /// then the larger priority value will win.
4785 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
4786 BufferCollectionTokenProxyInterface::r#set_name(self, priority, name)
4787 }
4788
4789 /// Set information about the current client that can be used by sysmem to
4790 /// help debug leaking memory and hangs waiting for constraints. |name| can
4791 /// be an arbitrary string, but the current process name (see
4792 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
4793 /// arbitrary id, but the current process ID (see
4794 /// fsl::GetCurrentProcessKoid()) is a good default.
4795 ///
4796 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
4797 /// indicate which client is closing their channel first, leading to
4798 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
4799 /// over, but if happening earlier than expected, the
4800 /// client-channel-specific name can help diagnose where the failure is
4801 /// first coming from, from sysmem's point of view).
4802 ///
4803 /// By default (unless overriden by this message or using
4804 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
4805 /// parent Node at the time the child Node is created. While this can be
4806 /// better than nothing, it's often better for each participant to use
4807 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
4808 /// info directly relevant to the current client. Also, SetVerboseLogging()
4809 /// can be used to help disambiguate if a Node is suspected of having info
4810 /// that was copied from its parent.
4811 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
4812 BufferCollectionTokenProxyInterface::r#set_debug_client_info(self, name, id)
4813 }
4814
4815 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
4816 /// after creating a collection. Clients can call this method to change
4817 /// when the log is printed. If multiple client set the deadline, it's
4818 /// unspecified which deadline will take effect.
4819 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
4820 BufferCollectionTokenProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
4821 }
4822
4823 /// Verbose logging includes constraints set via SetConstraints() from each
4824 /// client along with info set via SetDebugClientInfo() and the structure of
4825 /// the tree of Node(s).
4826 ///
4827 /// Normally sysmem prints only a single line complaint when aggregation
4828 /// fails, with just the specific detailed reason that aggregation failed,
4829 /// with minimal context. While this is often enough to diagnose a problem
4830 /// if only a small change was made and the system had been working before
4831 /// the small change, it's often not particularly helpful for getting a new
4832 /// buffer collection to work for the first time. Especially with more
4833 /// complex trees of nodes, involving things like AttachToken(),
4834 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
4835 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
4836 /// looks like and why it's failing a logical allocation, or why a tree or
4837 /// sub-tree is failing sooner than expected.
4838 ///
4839 /// The intent of the extra logging is to be acceptable from a performance
4840 /// point of view, if only enabled on a low number of buffer collections.
4841 /// If we're not tracking down a bug, we shouldn't send this message.
4842 ///
4843 /// If too many participants leave verbose logging enabled, we may end up
4844 /// needing to require that system-wide sysmem verbose logging be permitted
4845 /// via some other setting, to avoid sysmem spamming the log too much due to
4846 /// this message.
4847 ///
4848 /// This may be a NOP for some nodes due to intentional policy associated
4849 /// with the node, if we don't trust a node enough to let it turn on verbose
4850 /// logging.
4851 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
4852 BufferCollectionTokenProxyInterface::r#set_verbose_logging(self)
4853 }
4854
4855 /// This gets an event handle that can be used as a parameter to
4856 /// IsAlternateFor() called on any Node. The client will not be granted the
4857 /// right to signal this event, as this handle should only be used as proof
4858 /// that the client obtained this handle from this Node.
4859 ///
4860 /// Because this is a get not a set, no Sync() is needed between the
4861 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
4862 /// potentially being on different channels.
4863 ///
4864 /// See also IsAlternateFor().
4865 pub fn r#get_node_ref(
4866 &self,
4867 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
4868 {
4869 BufferCollectionTokenProxyInterface::r#get_node_ref(self)
4870 }
4871
4872 /// This checks whether the calling node is in a subtree rooted at a
4873 /// different child token of a common parent BufferCollectionTokenGroup, in
4874 /// relation to the passed-in node_ref.
4875 ///
4876 /// This call is for assisting with admission control de-duplication, and
4877 /// with debugging.
4878 ///
4879 /// The node_ref must be obtained using GetNodeRef() of a
4880 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
4881 ///
4882 /// The node_ref can be a duplicated handle; it's not necessary to call
4883 /// GetNodeRef() for every call to IsAlternateFor().
4884 ///
4885 /// If a calling token may not actually be a valid token at all due to
4886 /// a potentially hostile/untrusted provider of the token, call
4887 /// ValidateBufferCollectionToken() first instead of potentially getting
4888 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
4889 /// token not being a real token (not really talking to sysmem). Another
4890 /// option is to call BindSharedCollection with this token first which also
4891 /// validates the token along with converting it to a BufferCollection, then
4892 /// call BufferCollection IsAlternateFor().
4893 ///
4894 /// error values:
4895 ///
4896 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
4897 /// buffer collection as the calling Node. Before logical allocation and
4898 /// within the same logical allocation sub-tree, this essentially means that
4899 /// the node_ref was never part of this logical buffer collection, since
4900 /// before logical allocation all node_refs that come into existence remain
4901 /// in existence at least until logical allocation (including Node(s) that
4902 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
4903 /// to be returned, this Node's channel needs to still be connected server
4904 /// side, which won't be the case if the whole logical allocation has
4905 /// failed. After logical allocation or in a different logical allocation
4906 /// sub-tree there are additional potential reasons for this error. For
4907 /// example a different logical allocation (separated from this Node(s)
4908 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
4909 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
4910 /// exist and may select a different child sub-tree than the sub-tree the
4911 /// node_ref is in causing deletion of the node_ref Node. The only time
4912 /// sysmem keeps a Node around after that Node has no corresponding channel
4913 /// is when Close() is used and the Node's sub-tree has not yet failed.
4914 /// Another reason for this error is if the node_ref is an eventpair handle
4915 /// with sufficient rights, but isn't actually a real node_ref obtained from
4916 /// GetNodeRef().
4917 ///
4918 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
4919 /// eventpair handle, or doesn't have the needed rights expected on a real
4920 /// node_ref.
4921 ///
4922 /// No other failing status codes are returned by this call. However,
4923 /// sysmem may add additional codes in future, so the client should have
4924 /// sensible default handling for any failing status code.
4925 ///
4926 /// On success, is_alternate has the following meaning:
4927 /// * true - The first parent node in common between the calling node and
4928 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
4929 /// the calling Node and the node_ref Node will _not_ have both their
4930 /// constraints apply - rather sysmem will choose one or the other of
4931 /// the constraints - never both. This is because only one child of
4932 /// a BufferCollectionTokenGroup is selected during logical allocation,
4933 /// with only that one child's sub-tree contributing to constraints
4934 /// aggregation.
4935 /// * false - The first parent node in common between the calling Node and
4936 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
4937 /// this means the first parent node in common is a
4938 /// BufferCollectionToken or BufferCollection (regardless of not
4939 /// Close()ed or Close()ed). This means that the calling Node and the
4940 /// node_ref Node _may_ have both their constraints apply during
4941 /// constraints aggregation of the logical allocation, if both Node(s)
4942 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
4943 /// In this case, there is no BufferCollectionTokenGroup that will
4944 /// directly prevent the two Node(s) from both being selected and their
4945 /// constraints both aggregated, but even when false, one or both
4946 /// Node(s) may still be eliminated from consideration if one or both
4947 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
4948 /// which selects a child sub-tree other than the sub-tree containing
4949 /// the calling Node or node_ref Node.
4950 pub fn r#is_alternate_for(
4951 &self,
4952 mut node_ref: fidl::Event,
4953 ) -> fidl::client::QueryResponseFut<
4954 NodeIsAlternateForResult,
4955 fidl::encoding::DefaultFuchsiaResourceDialect,
4956 > {
4957 BufferCollectionTokenProxyInterface::r#is_alternate_for(self, node_ref)
4958 }
4959
4960 /// This method can be used to add more participants prior to creating a
4961 /// shared BufferCollection. A new token will be returned for each entry in
4962 /// the `rights_attenuation_masks` array. The return value is the client
4963 /// ends of each new participant token.
4964 ///
4965 /// If the calling token may not actually be a valid token at all due to
4966 /// a potentially hostile/untrusted provider of the token, consider using
4967 /// ValidateBufferCollectionToken() first instead of potentially getting
4968 /// stuck indefinitely if DuplicateSync() never responds due to the calling
4969 /// token not being a real token.
4970 ///
4971 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
4972 /// after calling this method.
4973 ///
4974 /// All tokens must be turned in via BindSharedCollection() or Close() for a
4975 /// BufferCollection to be successfully created.
4976 ///
4977 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
4978 /// will be absent in the buffer VMO rights obtainable via the corresponding
4979 /// returned token. This allows an initiator or intermediary participant to
4980 /// attenuate the rights available to a participant. This does not allow a
4981 /// participant to gain rights that the participant doesn't already have.
4982 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
4983 /// attenuation should be applied.
4984 pub fn r#duplicate_sync(
4985 &self,
4986 mut rights_attenuation_masks: &[fidl::Rights],
4987 ) -> fidl::client::QueryResponseFut<
4988 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
4989 fidl::encoding::DefaultFuchsiaResourceDialect,
4990 > {
4991 BufferCollectionTokenProxyInterface::r#duplicate_sync(self, rights_attenuation_masks)
4992 }
4993
4994 /// This method can be used to add a participant prior to creating a shared
4995 /// BufferCollection. It should only be used instead of DuplicateSync in
4996 /// performance sensitive cases where it would be undesireable to wait for
4997 /// sysmem to respond as part of each duplicate.
4998 ///
4999 /// After sending one or more Duplicate() messages, and before sending the
5000 /// created tokens to other participants (or to other Allocator channels),
5001 /// the client should send a Sync() and wait for its response. The Sync()
5002 /// call can be made on the token, or on the BufferCollection obtained by
5003 /// passing this token to BindSharedCollection(). Either will ensure that
5004 /// the server knows about the tokens created via Duplicate() before the
5005 /// other participant sends the token to the server via separate Allocator
5006 /// channel.
5007 ///
5008 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5009 /// BufferCollection to be successfully created.
5010 ///
5011 /// When a client calls BindSharedCollection() to turn in a
5012 /// BufferCollectionToken, the server will process all Duplicate() messages
5013 /// before closing down the BufferCollectionToken. This allows the client
5014 /// to Duplicate() and immediately turn in the BufferCollectionToken using
5015 /// BindSharedCollection, then later transfer the client end of token_request
5016 /// to another participant - the server will notice the existence of the
5017 /// token_request before considering this BufferCollectionToken fully closed.
5018 ///
5019 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
5020 /// absent in the buffer VMO rights obtainable via the client end of
5021 /// token_request. This allows an initiator or intermediary participant to
5022 /// attenuate the rights available to a participant. This does not allow a
5023 /// participant to gain rights that the participant doesn't already have.
5024 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5025 /// attenuation should be applied.
5026 ///
5027 /// These values for rights_attenuation_mask result in no attenuation:
5028 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
5029 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
5030 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
5031 ///
5032 /// `token_request` is the server end of a BufferCollectionToken channel.
5033 /// The client end of this channel acts as another participant in creating the
5034 /// shared BufferCollection.
5035 pub fn r#duplicate(
5036 &self,
5037 mut rights_attenuation_mask: u32,
5038 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5039 ) -> Result<(), fidl::Error> {
5040 BufferCollectionTokenProxyInterface::r#duplicate(
5041 self,
5042 rights_attenuation_mask,
5043 token_request,
5044 )
5045 }
5046
5047 /// A dispensable token can fail after buffers are logically allocated
5048 /// without causing failure of its parent (if any).
5049 ///
5050 /// The dispensable token participates in constraints aggregation along with
5051 /// its parent before logical buffer allocation. If the dispensable token
5052 /// fails before buffers are logically allocated, the failure propagates to
5053 /// the dispensable token's parent.
5054 ///
5055 /// After buffers are logically allocated, failure of the dispensable token
5056 /// (or any child of the dispensable token) does not propagate to the
5057 /// dispensable token's parent. Failure does propagate from a normal
5058 /// child of a dispensable token to the dispensable token. Failure
5059 /// of a child is blocked from reaching its parent if the child is attached,
5060 /// or if the child is dispensable and the failure occurred after logical
5061 /// allocation.
5062 ///
5063 /// A dispensable token can be used in cases where a participant needs to
5064 /// provide constraints, but after buffers are allocated, the participant
5065 /// can fail without causing buffer collection failure from the parent's
5066 /// point of view.
5067 ///
5068 /// In contrast, AttachToken() can be used to create a token which does not
5069 /// participate in constraints aggregation with its parent, and whose
5070 /// failure at any time does not propagate to its parent, and whose delay
5071 /// providing constraints does not prevent the parent from completing its
5072 /// buffer allocation.
5073 ///
5074 /// An initiator may in some scenarios choose to initially use a dispensable
5075 /// token for a given instance of a participant, and then later if the first
5076 /// instance of that participant fails, a new second instance of that
5077 /// participant my be given a token created with AttachToken().
5078 ///
5079 /// If a client uses this message, the client should not rely on the
5080 /// client's own BufferCollectionToken or BufferCollection channel to close
5081 /// from the server end due to abrupt failure of any BufferCollectionToken
5082 /// or BufferCollection that the client has SetDispensable() and given out
5083 /// to another process. For this reason, the client should take extra care
5084 /// to notice failure of that other process via other means.
5085 ///
5086 /// While it is possible (and potentially useful) to SetDispensable() on a
5087 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
5088 /// replace a failed dispensable token that was a direct child of a group
5089 /// with a new token using AttachToken() (since there's no AttachToken() on
5090 /// a group). Instead, to enable AttachToken() replacement in this case,
5091 /// create an additional non-dispensable token (node) that's a direct child
5092 /// of the group and make the existing dispensable token a child of the
5093 /// additional token (node). This way, the additional token (node) that is
5094 /// a direct child of the group has BufferCollection.AttachToken() which can
5095 /// be used to replace the failed dispensable token.
5096 ///
5097 /// SetDispensable() on an already-dispensable token is idempotent.
5098 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
5099 BufferCollectionTokenProxyInterface::r#set_dispensable(self)
5100 }
5101
5102 /// Most sysmem clients and many participants don't need to care about this
5103 /// message or about BufferCollectionTokenGroup(s) in general.
5104 ///
5105 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
5106 /// tokens. The child tokens which are not selected during aggregation will
5107 /// fail (close), which a potential participant should notice when their
5108 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
5109 /// participant to clean up the speculative usage that didn't end up
5110 /// happening (similarly to a normal BufferCollection server end closing
5111 /// on failure of a logical buffer collection).
5112 ///
5113 /// See comments on protocol BufferCollectionTokenGroup.
5114 ///
5115 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
5116 /// applied to the whole group can be achieved with a token for this purpose
5117 /// as a direct parent of the group.
5118 ///
5119 /// group_request - the server end of a BufferCollectionTokenGroup channel
5120 /// to be served by sysmem.
5121 pub fn r#create_buffer_collection_token_group(
5122 &self,
5123 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
5124 ) -> Result<(), fidl::Error> {
5125 BufferCollectionTokenProxyInterface::r#create_buffer_collection_token_group(
5126 self,
5127 group_request,
5128 )
5129 }
5130}
5131
5132impl BufferCollectionTokenProxyInterface for BufferCollectionTokenProxy {
5133 type SyncResponseFut =
5134 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
5135 fn r#sync(&self) -> Self::SyncResponseFut {
5136 fn _decode(
5137 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5138 ) -> Result<(), fidl::Error> {
5139 let _response = fidl::client::decode_transaction_body::<
5140 fidl::encoding::EmptyPayload,
5141 fidl::encoding::DefaultFuchsiaResourceDialect,
5142 0x4577e238ae26291,
5143 >(_buf?)?;
5144 Ok(_response)
5145 }
5146 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
5147 (),
5148 0x4577e238ae26291,
5149 fidl::encoding::DynamicFlags::empty(),
5150 _decode,
5151 )
5152 }
5153
5154 fn r#close(&self) -> Result<(), fidl::Error> {
5155 self.client.send::<fidl::encoding::EmptyPayload>(
5156 (),
5157 0x5b1d7a4f5681fca7,
5158 fidl::encoding::DynamicFlags::empty(),
5159 )
5160 }
5161
5162 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
5163 self.client.send::<NodeSetNameRequest>(
5164 (priority, name),
5165 0x77a41bb6217e2443,
5166 fidl::encoding::DynamicFlags::empty(),
5167 )
5168 }
5169
5170 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
5171 self.client.send::<NodeSetDebugClientInfoRequest>(
5172 (name, id),
5173 0x7275759070eb5ee2,
5174 fidl::encoding::DynamicFlags::empty(),
5175 )
5176 }
5177
5178 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
5179 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
5180 (deadline,),
5181 0x46d38f4772638867,
5182 fidl::encoding::DynamicFlags::empty(),
5183 )
5184 }
5185
5186 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
5187 self.client.send::<fidl::encoding::EmptyPayload>(
5188 (),
5189 0x6bfbe2cf1701d288,
5190 fidl::encoding::DynamicFlags::empty(),
5191 )
5192 }
5193
5194 type GetNodeRefResponseFut =
5195 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
5196 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
5197 fn _decode(
5198 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5199 ) -> Result<fidl::Event, fidl::Error> {
5200 let _response = fidl::client::decode_transaction_body::<
5201 NodeGetNodeRefResponse,
5202 fidl::encoding::DefaultFuchsiaResourceDialect,
5203 0x467b7c75c35c3b84,
5204 >(_buf?)?;
5205 Ok(_response.node_ref)
5206 }
5207 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
5208 (),
5209 0x467b7c75c35c3b84,
5210 fidl::encoding::DynamicFlags::empty(),
5211 _decode,
5212 )
5213 }
5214
5215 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
5216 NodeIsAlternateForResult,
5217 fidl::encoding::DefaultFuchsiaResourceDialect,
5218 >;
5219 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
5220 fn _decode(
5221 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5222 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
5223 let _response = fidl::client::decode_transaction_body::<
5224 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
5225 fidl::encoding::DefaultFuchsiaResourceDialect,
5226 0x33a2a7aff2776c07,
5227 >(_buf?)?;
5228 Ok(_response.map(|x| x.is_alternate))
5229 }
5230 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
5231 (node_ref,),
5232 0x33a2a7aff2776c07,
5233 fidl::encoding::DynamicFlags::empty(),
5234 _decode,
5235 )
5236 }
5237
5238 type DuplicateSyncResponseFut = fidl::client::QueryResponseFut<
5239 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
5240 fidl::encoding::DefaultFuchsiaResourceDialect,
5241 >;
5242 fn r#duplicate_sync(
5243 &self,
5244 mut rights_attenuation_masks: &[fidl::Rights],
5245 ) -> Self::DuplicateSyncResponseFut {
5246 fn _decode(
5247 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5248 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error>
5249 {
5250 let _response = fidl::client::decode_transaction_body::<
5251 BufferCollectionTokenDuplicateSyncResponse,
5252 fidl::encoding::DefaultFuchsiaResourceDialect,
5253 0x49ed7ab7cc19f18,
5254 >(_buf?)?;
5255 Ok(_response.tokens)
5256 }
5257 self.client.send_query_and_decode::<
5258 BufferCollectionTokenDuplicateSyncRequest,
5259 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
5260 >(
5261 (rights_attenuation_masks,),
5262 0x49ed7ab7cc19f18,
5263 fidl::encoding::DynamicFlags::empty(),
5264 _decode,
5265 )
5266 }
5267
5268 fn r#duplicate(
5269 &self,
5270 mut rights_attenuation_mask: u32,
5271 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5272 ) -> Result<(), fidl::Error> {
5273 self.client.send::<BufferCollectionTokenDuplicateRequest>(
5274 (rights_attenuation_mask, token_request),
5275 0x2f9f81bdde4b7292,
5276 fidl::encoding::DynamicFlags::empty(),
5277 )
5278 }
5279
5280 fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
5281 self.client.send::<fidl::encoding::EmptyPayload>(
5282 (),
5283 0x76e4ec34fc2cf5b3,
5284 fidl::encoding::DynamicFlags::empty(),
5285 )
5286 }
5287
5288 fn r#create_buffer_collection_token_group(
5289 &self,
5290 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
5291 ) -> Result<(), fidl::Error> {
5292 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
5293 (group_request,),
5294 0x2f6243e05f22b9a7,
5295 fidl::encoding::DynamicFlags::empty(),
5296 )
5297 }
5298}
5299
5300pub struct BufferCollectionTokenEventStream {
5301 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
5302}
5303
5304impl std::marker::Unpin for BufferCollectionTokenEventStream {}
5305
5306impl futures::stream::FusedStream for BufferCollectionTokenEventStream {
5307 fn is_terminated(&self) -> bool {
5308 self.event_receiver.is_terminated()
5309 }
5310}
5311
5312impl futures::Stream for BufferCollectionTokenEventStream {
5313 type Item = Result<BufferCollectionTokenEvent, fidl::Error>;
5314
5315 fn poll_next(
5316 mut self: std::pin::Pin<&mut Self>,
5317 cx: &mut std::task::Context<'_>,
5318 ) -> std::task::Poll<Option<Self::Item>> {
5319 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
5320 &mut self.event_receiver,
5321 cx
5322 )?) {
5323 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenEvent::decode(buf))),
5324 None => std::task::Poll::Ready(None),
5325 }
5326 }
5327}
5328
5329#[derive(Debug)]
5330pub enum BufferCollectionTokenEvent {}
5331
5332impl BufferCollectionTokenEvent {
5333 /// Decodes a message buffer as a [`BufferCollectionTokenEvent`].
5334 fn decode(
5335 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
5336 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
5337 let (bytes, _handles) = buf.split_mut();
5338 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
5339 debug_assert_eq!(tx_header.tx_id, 0);
5340 match tx_header.ordinal {
5341 _ => Err(fidl::Error::UnknownOrdinal {
5342 ordinal: tx_header.ordinal,
5343 protocol_name:
5344 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
5345 }),
5346 }
5347 }
5348}
5349
5350/// A Stream of incoming requests for fuchsia.sysmem/BufferCollectionToken.
5351pub struct BufferCollectionTokenRequestStream {
5352 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
5353 is_terminated: bool,
5354}
5355
5356impl std::marker::Unpin for BufferCollectionTokenRequestStream {}
5357
5358impl futures::stream::FusedStream for BufferCollectionTokenRequestStream {
5359 fn is_terminated(&self) -> bool {
5360 self.is_terminated
5361 }
5362}
5363
5364impl fidl::endpoints::RequestStream for BufferCollectionTokenRequestStream {
5365 type Protocol = BufferCollectionTokenMarker;
5366 type ControlHandle = BufferCollectionTokenControlHandle;
5367
5368 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
5369 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
5370 }
5371
5372 fn control_handle(&self) -> Self::ControlHandle {
5373 BufferCollectionTokenControlHandle { inner: self.inner.clone() }
5374 }
5375
5376 fn into_inner(
5377 self,
5378 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
5379 {
5380 (self.inner, self.is_terminated)
5381 }
5382
5383 fn from_inner(
5384 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
5385 is_terminated: bool,
5386 ) -> Self {
5387 Self { inner, is_terminated }
5388 }
5389}
5390
5391impl futures::Stream for BufferCollectionTokenRequestStream {
5392 type Item = Result<BufferCollectionTokenRequest, fidl::Error>;
5393
5394 fn poll_next(
5395 mut self: std::pin::Pin<&mut Self>,
5396 cx: &mut std::task::Context<'_>,
5397 ) -> std::task::Poll<Option<Self::Item>> {
5398 let this = &mut *self;
5399 if this.inner.check_shutdown(cx) {
5400 this.is_terminated = true;
5401 return std::task::Poll::Ready(None);
5402 }
5403 if this.is_terminated {
5404 panic!("polled BufferCollectionTokenRequestStream after completion");
5405 }
5406 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
5407 |bytes, handles| {
5408 match this.inner.channel().read_etc(cx, bytes, handles) {
5409 std::task::Poll::Ready(Ok(())) => {}
5410 std::task::Poll::Pending => return std::task::Poll::Pending,
5411 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
5412 this.is_terminated = true;
5413 return std::task::Poll::Ready(None);
5414 }
5415 std::task::Poll::Ready(Err(e)) => {
5416 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
5417 e.into(),
5418 ))));
5419 }
5420 }
5421
5422 // A message has been received from the channel
5423 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
5424
5425 std::task::Poll::Ready(Some(match header.ordinal {
5426 0x4577e238ae26291 => {
5427 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5428 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5429 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5430 let control_handle = BufferCollectionTokenControlHandle {
5431 inner: this.inner.clone(),
5432 };
5433 Ok(BufferCollectionTokenRequest::Sync {
5434 responder: BufferCollectionTokenSyncResponder {
5435 control_handle: std::mem::ManuallyDrop::new(control_handle),
5436 tx_id: header.tx_id,
5437 },
5438 })
5439 }
5440 0x5b1d7a4f5681fca7 => {
5441 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5442 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5443 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5444 let control_handle = BufferCollectionTokenControlHandle {
5445 inner: this.inner.clone(),
5446 };
5447 Ok(BufferCollectionTokenRequest::Close {
5448 control_handle,
5449 })
5450 }
5451 0x77a41bb6217e2443 => {
5452 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5453 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5454 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
5455 let control_handle = BufferCollectionTokenControlHandle {
5456 inner: this.inner.clone(),
5457 };
5458 Ok(BufferCollectionTokenRequest::SetName {priority: req.priority,
5459name: req.name,
5460
5461 control_handle,
5462 })
5463 }
5464 0x7275759070eb5ee2 => {
5465 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5466 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5467 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
5468 let control_handle = BufferCollectionTokenControlHandle {
5469 inner: this.inner.clone(),
5470 };
5471 Ok(BufferCollectionTokenRequest::SetDebugClientInfo {name: req.name,
5472id: req.id,
5473
5474 control_handle,
5475 })
5476 }
5477 0x46d38f4772638867 => {
5478 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5479 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5480 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
5481 let control_handle = BufferCollectionTokenControlHandle {
5482 inner: this.inner.clone(),
5483 };
5484 Ok(BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {deadline: req.deadline,
5485
5486 control_handle,
5487 })
5488 }
5489 0x6bfbe2cf1701d288 => {
5490 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5491 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5492 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5493 let control_handle = BufferCollectionTokenControlHandle {
5494 inner: this.inner.clone(),
5495 };
5496 Ok(BufferCollectionTokenRequest::SetVerboseLogging {
5497 control_handle,
5498 })
5499 }
5500 0x467b7c75c35c3b84 => {
5501 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5502 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5503 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5504 let control_handle = BufferCollectionTokenControlHandle {
5505 inner: this.inner.clone(),
5506 };
5507 Ok(BufferCollectionTokenRequest::GetNodeRef {
5508 responder: BufferCollectionTokenGetNodeRefResponder {
5509 control_handle: std::mem::ManuallyDrop::new(control_handle),
5510 tx_id: header.tx_id,
5511 },
5512 })
5513 }
5514 0x33a2a7aff2776c07 => {
5515 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5516 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5517 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
5518 let control_handle = BufferCollectionTokenControlHandle {
5519 inner: this.inner.clone(),
5520 };
5521 Ok(BufferCollectionTokenRequest::IsAlternateFor {node_ref: req.node_ref,
5522
5523 responder: BufferCollectionTokenIsAlternateForResponder {
5524 control_handle: std::mem::ManuallyDrop::new(control_handle),
5525 tx_id: header.tx_id,
5526 },
5527 })
5528 }
5529 0x49ed7ab7cc19f18 => {
5530 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5531 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5532 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateSyncRequest>(&header, _body_bytes, handles, &mut req)?;
5533 let control_handle = BufferCollectionTokenControlHandle {
5534 inner: this.inner.clone(),
5535 };
5536 Ok(BufferCollectionTokenRequest::DuplicateSync {rights_attenuation_masks: req.rights_attenuation_masks,
5537
5538 responder: BufferCollectionTokenDuplicateSyncResponder {
5539 control_handle: std::mem::ManuallyDrop::new(control_handle),
5540 tx_id: header.tx_id,
5541 },
5542 })
5543 }
5544 0x2f9f81bdde4b7292 => {
5545 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5546 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5547 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateRequest>(&header, _body_bytes, handles, &mut req)?;
5548 let control_handle = BufferCollectionTokenControlHandle {
5549 inner: this.inner.clone(),
5550 };
5551 Ok(BufferCollectionTokenRequest::Duplicate {rights_attenuation_mask: req.rights_attenuation_mask,
5552token_request: req.token_request,
5553
5554 control_handle,
5555 })
5556 }
5557 0x76e4ec34fc2cf5b3 => {
5558 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5559 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5560 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5561 let control_handle = BufferCollectionTokenControlHandle {
5562 inner: this.inner.clone(),
5563 };
5564 Ok(BufferCollectionTokenRequest::SetDispensable {
5565 control_handle,
5566 })
5567 }
5568 0x2f6243e05f22b9a7 => {
5569 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5570 let mut req = fidl::new_empty!(BufferCollectionTokenCreateBufferCollectionTokenGroupRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5571 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(&header, _body_bytes, handles, &mut req)?;
5572 let control_handle = BufferCollectionTokenControlHandle {
5573 inner: this.inner.clone(),
5574 };
5575 Ok(BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {group_request: req.group_request,
5576
5577 control_handle,
5578 })
5579 }
5580 _ => Err(fidl::Error::UnknownOrdinal {
5581 ordinal: header.ordinal,
5582 protocol_name: <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
5583 }),
5584 }))
5585 },
5586 )
5587 }
5588}
5589
5590/// A BufferCollectionToken is not a BufferCollection, but rather a way to
5591/// identify a potential shared BufferCollection prior to the BufferCollection
5592/// being allocated.
5593///
5594/// We use a channel for the BufferCollectionToken instead of a single eventpair
5595/// (pair) because this way we can detect error conditions like a participant
5596/// dying mid-create.
5597///
5598/// The fuchsia.sysmem.BufferCollectionToken type is not yet deprecated due to
5599/// its use in some other protocols (for now), but all the internals of
5600/// fuchsia.sysmem.BufferCollectionToken are deprecated. Token channels serve
5601/// both fuchsia.sysmem.BufferCollectionToken and
5602/// fuchsia.sysmem2.BufferCollectionToken.
5603///
5604/// This protocol will be deprecated once other protocols have switched their
5605/// token fields to fuchsia.sysmem2.BufferCollectionToken.
5606#[derive(Debug)]
5607pub enum BufferCollectionTokenRequest {
5608 /// Ensure that previous messages, including Duplicate() messages on a
5609 /// token, collection, or group, have been received server side.
5610 ///
5611 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
5612 /// valid sysmem token risks the Sync() hanging forever. See
5613 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
5614 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
5615 /// Another way is to pass the token to BindSharedCollection(), which also
5616 /// validates the token as part of exchanging it for a BufferCollection
5617 /// channel, and BufferCollection Sync() can then be used.
5618 ///
5619 /// After a Sync(), it's then safe to send the client end of token_request
5620 /// to another participant knowing the server will recognize the token when
5621 /// it's sent into BindSharedCollection() by the other participant.
5622 ///
5623 /// Other options include waiting for each token.Duplicate() to complete
5624 /// individually (using separate call to token.Sync() after each), or
5625 /// calling Sync() on BufferCollection after the token has been turned in
5626 /// via BindSharedCollection().
5627 ///
5628 /// Another way to mitigate is to avoid calling Sync() on the token, and
5629 /// instead later deal with potential failure of BufferCollection.Sync() if
5630 /// the original token was invalid. This option can be preferable from a
5631 /// performance point of view, but requires client code to delay sending
5632 /// tokens duplicated from this token until after client code has converted
5633 /// the duplicating token to a BufferCollection and received successful
5634 /// response from BufferCollection.Sync().
5635 ///
5636 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
5637 /// When BufferCollection.Sync() isn't feasible, the caller must already
5638 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
5639 /// hang forever. See ValidateBufferCollectionToken() to check token
5640 /// validity first if the token isn't already known to be (is/was) valid.
5641 Sync { responder: BufferCollectionTokenSyncResponder },
5642 /// On a BufferCollectionToken channel:
5643 ///
5644 /// Normally a participant will convert a BufferCollectionToken into a
5645 /// BufferCollection view, but a participant is also free to Close() the
5646 /// token (and then close the channel immediately or shortly later in
5647 /// response to server closing its end), which avoids causing logical buffer
5648 /// collection failure. Â Normally an unexpected token channel close will
5649 /// cause logical buffer collection failure (the only exceptions being
5650 /// certain cases involving AttachToken() or SetDispensable()).
5651 ///
5652 /// On a BufferCollection channel:
5653 ///
5654 /// By default the server handles unexpected failure of a BufferCollection
5655 /// by failing the whole logical buffer collection. Partly this is to
5656 /// expedite closing VMO handles to reclaim memory when any participant
5657 /// fails. If a participant would like to cleanly close a BufferCollection
5658 /// view without causing logical buffer collection failure, the participant
5659 /// can send Close() before closing the client end of the BufferCollection
5660 /// channel. If this is the last BufferCollection view, the logical buffer
5661 /// collection will still go away. The Close() can occur before or after
5662 /// SetConstraints(). If before SetConstraints(), the buffer collection
5663 /// won't require constraints from this node in order to allocate. If
5664 /// after SetConstraints(), the constraints are retained and aggregated
5665 /// along with any subsequent logical allocation(s), despite the lack of
5666 /// channel connection.
5667 ///
5668 /// On a BufferCollectionTokenGroup channel:
5669 ///
5670 /// By default, unexpected failure of a BufferCollectionTokenGroup will
5671 /// trigger failure of the logical BufferCollectionTokenGroup and will
5672 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
5673 /// channel without failing the logical group or propagating failure, send
5674 /// Close() before closing the channel client endpoint.
5675 ///
5676 /// If Close() occurs before AllChildrenPresent(), the logical buffer
5677 /// collection will still fail despite the Close() (because sysmem can't be
5678 /// sure whether all relevant children were created, so it's ambiguous
5679 /// whether all relevant constraints will be provided to sysmem). If
5680 /// Close() occurs after AllChildrenPresent(), the children and all their
5681 /// constraints remain intact (just as they would if the
5682 /// BufferCollectionTokenGroup channel had remained open), and the close
5683 /// doesn't trigger or propagate failure.
5684 Close { control_handle: BufferCollectionTokenControlHandle },
5685 /// Set a name for VMOs in this buffer collection. The name may be truncated
5686 /// shorter. The name only affects VMOs allocated after it's set - this call
5687 /// does not rename existing VMOs. If multiple clients set different names
5688 /// then the larger priority value will win.
5689 SetName { priority: u32, name: String, control_handle: BufferCollectionTokenControlHandle },
5690 /// Set information about the current client that can be used by sysmem to
5691 /// help debug leaking memory and hangs waiting for constraints. |name| can
5692 /// be an arbitrary string, but the current process name (see
5693 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
5694 /// arbitrary id, but the current process ID (see
5695 /// fsl::GetCurrentProcessKoid()) is a good default.
5696 ///
5697 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
5698 /// indicate which client is closing their channel first, leading to
5699 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
5700 /// over, but if happening earlier than expected, the
5701 /// client-channel-specific name can help diagnose where the failure is
5702 /// first coming from, from sysmem's point of view).
5703 ///
5704 /// By default (unless overriden by this message or using
5705 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
5706 /// parent Node at the time the child Node is created. While this can be
5707 /// better than nothing, it's often better for each participant to use
5708 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
5709 /// info directly relevant to the current client. Also, SetVerboseLogging()
5710 /// can be used to help disambiguate if a Node is suspected of having info
5711 /// that was copied from its parent.
5712 SetDebugClientInfo { name: String, id: u64, control_handle: BufferCollectionTokenControlHandle },
5713 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
5714 /// after creating a collection. Clients can call this method to change
5715 /// when the log is printed. If multiple client set the deadline, it's
5716 /// unspecified which deadline will take effect.
5717 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: BufferCollectionTokenControlHandle },
5718 /// Verbose logging includes constraints set via SetConstraints() from each
5719 /// client along with info set via SetDebugClientInfo() and the structure of
5720 /// the tree of Node(s).
5721 ///
5722 /// Normally sysmem prints only a single line complaint when aggregation
5723 /// fails, with just the specific detailed reason that aggregation failed,
5724 /// with minimal context. While this is often enough to diagnose a problem
5725 /// if only a small change was made and the system had been working before
5726 /// the small change, it's often not particularly helpful for getting a new
5727 /// buffer collection to work for the first time. Especially with more
5728 /// complex trees of nodes, involving things like AttachToken(),
5729 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
5730 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
5731 /// looks like and why it's failing a logical allocation, or why a tree or
5732 /// sub-tree is failing sooner than expected.
5733 ///
5734 /// The intent of the extra logging is to be acceptable from a performance
5735 /// point of view, if only enabled on a low number of buffer collections.
5736 /// If we're not tracking down a bug, we shouldn't send this message.
5737 ///
5738 /// If too many participants leave verbose logging enabled, we may end up
5739 /// needing to require that system-wide sysmem verbose logging be permitted
5740 /// via some other setting, to avoid sysmem spamming the log too much due to
5741 /// this message.
5742 ///
5743 /// This may be a NOP for some nodes due to intentional policy associated
5744 /// with the node, if we don't trust a node enough to let it turn on verbose
5745 /// logging.
5746 SetVerboseLogging { control_handle: BufferCollectionTokenControlHandle },
5747 /// This gets an event handle that can be used as a parameter to
5748 /// IsAlternateFor() called on any Node. The client will not be granted the
5749 /// right to signal this event, as this handle should only be used as proof
5750 /// that the client obtained this handle from this Node.
5751 ///
5752 /// Because this is a get not a set, no Sync() is needed between the
5753 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
5754 /// potentially being on different channels.
5755 ///
5756 /// See also IsAlternateFor().
5757 GetNodeRef { responder: BufferCollectionTokenGetNodeRefResponder },
5758 /// This checks whether the calling node is in a subtree rooted at a
5759 /// different child token of a common parent BufferCollectionTokenGroup, in
5760 /// relation to the passed-in node_ref.
5761 ///
5762 /// This call is for assisting with admission control de-duplication, and
5763 /// with debugging.
5764 ///
5765 /// The node_ref must be obtained using GetNodeRef() of a
5766 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
5767 ///
5768 /// The node_ref can be a duplicated handle; it's not necessary to call
5769 /// GetNodeRef() for every call to IsAlternateFor().
5770 ///
5771 /// If a calling token may not actually be a valid token at all due to
5772 /// a potentially hostile/untrusted provider of the token, call
5773 /// ValidateBufferCollectionToken() first instead of potentially getting
5774 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
5775 /// token not being a real token (not really talking to sysmem). Another
5776 /// option is to call BindSharedCollection with this token first which also
5777 /// validates the token along with converting it to a BufferCollection, then
5778 /// call BufferCollection IsAlternateFor().
5779 ///
5780 /// error values:
5781 ///
5782 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
5783 /// buffer collection as the calling Node. Before logical allocation and
5784 /// within the same logical allocation sub-tree, this essentially means that
5785 /// the node_ref was never part of this logical buffer collection, since
5786 /// before logical allocation all node_refs that come into existence remain
5787 /// in existence at least until logical allocation (including Node(s) that
5788 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
5789 /// to be returned, this Node's channel needs to still be connected server
5790 /// side, which won't be the case if the whole logical allocation has
5791 /// failed. After logical allocation or in a different logical allocation
5792 /// sub-tree there are additional potential reasons for this error. For
5793 /// example a different logical allocation (separated from this Node(s)
5794 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
5795 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
5796 /// exist and may select a different child sub-tree than the sub-tree the
5797 /// node_ref is in causing deletion of the node_ref Node. The only time
5798 /// sysmem keeps a Node around after that Node has no corresponding channel
5799 /// is when Close() is used and the Node's sub-tree has not yet failed.
5800 /// Another reason for this error is if the node_ref is an eventpair handle
5801 /// with sufficient rights, but isn't actually a real node_ref obtained from
5802 /// GetNodeRef().
5803 ///
5804 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
5805 /// eventpair handle, or doesn't have the needed rights expected on a real
5806 /// node_ref.
5807 ///
5808 /// No other failing status codes are returned by this call. However,
5809 /// sysmem may add additional codes in future, so the client should have
5810 /// sensible default handling for any failing status code.
5811 ///
5812 /// On success, is_alternate has the following meaning:
5813 /// * true - The first parent node in common between the calling node and
5814 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
5815 /// the calling Node and the node_ref Node will _not_ have both their
5816 /// constraints apply - rather sysmem will choose one or the other of
5817 /// the constraints - never both. This is because only one child of
5818 /// a BufferCollectionTokenGroup is selected during logical allocation,
5819 /// with only that one child's sub-tree contributing to constraints
5820 /// aggregation.
5821 /// * false - The first parent node in common between the calling Node and
5822 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
5823 /// this means the first parent node in common is a
5824 /// BufferCollectionToken or BufferCollection (regardless of not
5825 /// Close()ed or Close()ed). This means that the calling Node and the
5826 /// node_ref Node _may_ have both their constraints apply during
5827 /// constraints aggregation of the logical allocation, if both Node(s)
5828 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
5829 /// In this case, there is no BufferCollectionTokenGroup that will
5830 /// directly prevent the two Node(s) from both being selected and their
5831 /// constraints both aggregated, but even when false, one or both
5832 /// Node(s) may still be eliminated from consideration if one or both
5833 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
5834 /// which selects a child sub-tree other than the sub-tree containing
5835 /// the calling Node or node_ref Node.
5836 IsAlternateFor {
5837 node_ref: fidl::Event,
5838 responder: BufferCollectionTokenIsAlternateForResponder,
5839 },
5840 /// This method can be used to add more participants prior to creating a
5841 /// shared BufferCollection. A new token will be returned for each entry in
5842 /// the `rights_attenuation_masks` array. The return value is the client
5843 /// ends of each new participant token.
5844 ///
5845 /// If the calling token may not actually be a valid token at all due to
5846 /// a potentially hostile/untrusted provider of the token, consider using
5847 /// ValidateBufferCollectionToken() first instead of potentially getting
5848 /// stuck indefinitely if DuplicateSync() never responds due to the calling
5849 /// token not being a real token.
5850 ///
5851 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
5852 /// after calling this method.
5853 ///
5854 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5855 /// BufferCollection to be successfully created.
5856 ///
5857 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
5858 /// will be absent in the buffer VMO rights obtainable via the corresponding
5859 /// returned token. This allows an initiator or intermediary participant to
5860 /// attenuate the rights available to a participant. This does not allow a
5861 /// participant to gain rights that the participant doesn't already have.
5862 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5863 /// attenuation should be applied.
5864 DuplicateSync {
5865 rights_attenuation_masks: Vec<fidl::Rights>,
5866 responder: BufferCollectionTokenDuplicateSyncResponder,
5867 },
5868 /// This method can be used to add a participant prior to creating a shared
5869 /// BufferCollection. It should only be used instead of DuplicateSync in
5870 /// performance sensitive cases where it would be undesireable to wait for
5871 /// sysmem to respond as part of each duplicate.
5872 ///
5873 /// After sending one or more Duplicate() messages, and before sending the
5874 /// created tokens to other participants (or to other Allocator channels),
5875 /// the client should send a Sync() and wait for its response. The Sync()
5876 /// call can be made on the token, or on the BufferCollection obtained by
5877 /// passing this token to BindSharedCollection(). Either will ensure that
5878 /// the server knows about the tokens created via Duplicate() before the
5879 /// other participant sends the token to the server via separate Allocator
5880 /// channel.
5881 ///
5882 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5883 /// BufferCollection to be successfully created.
5884 ///
5885 /// When a client calls BindSharedCollection() to turn in a
5886 /// BufferCollectionToken, the server will process all Duplicate() messages
5887 /// before closing down the BufferCollectionToken. This allows the client
5888 /// to Duplicate() and immediately turn in the BufferCollectionToken using
5889 /// BindSharedCollection, then later transfer the client end of token_request
5890 /// to another participant - the server will notice the existence of the
5891 /// token_request before considering this BufferCollectionToken fully closed.
5892 ///
5893 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
5894 /// absent in the buffer VMO rights obtainable via the client end of
5895 /// token_request. This allows an initiator or intermediary participant to
5896 /// attenuate the rights available to a participant. This does not allow a
5897 /// participant to gain rights that the participant doesn't already have.
5898 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5899 /// attenuation should be applied.
5900 ///
5901 /// These values for rights_attenuation_mask result in no attenuation:
5902 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
5903 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
5904 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
5905 ///
5906 /// `token_request` is the server end of a BufferCollectionToken channel.
5907 /// The client end of this channel acts as another participant in creating the
5908 /// shared BufferCollection.
5909 Duplicate {
5910 rights_attenuation_mask: u32,
5911 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5912 control_handle: BufferCollectionTokenControlHandle,
5913 },
5914 /// A dispensable token can fail after buffers are logically allocated
5915 /// without causing failure of its parent (if any).
5916 ///
5917 /// The dispensable token participates in constraints aggregation along with
5918 /// its parent before logical buffer allocation. If the dispensable token
5919 /// fails before buffers are logically allocated, the failure propagates to
5920 /// the dispensable token's parent.
5921 ///
5922 /// After buffers are logically allocated, failure of the dispensable token
5923 /// (or any child of the dispensable token) does not propagate to the
5924 /// dispensable token's parent. Failure does propagate from a normal
5925 /// child of a dispensable token to the dispensable token. Failure
5926 /// of a child is blocked from reaching its parent if the child is attached,
5927 /// or if the child is dispensable and the failure occurred after logical
5928 /// allocation.
5929 ///
5930 /// A dispensable token can be used in cases where a participant needs to
5931 /// provide constraints, but after buffers are allocated, the participant
5932 /// can fail without causing buffer collection failure from the parent's
5933 /// point of view.
5934 ///
5935 /// In contrast, AttachToken() can be used to create a token which does not
5936 /// participate in constraints aggregation with its parent, and whose
5937 /// failure at any time does not propagate to its parent, and whose delay
5938 /// providing constraints does not prevent the parent from completing its
5939 /// buffer allocation.
5940 ///
5941 /// An initiator may in some scenarios choose to initially use a dispensable
5942 /// token for a given instance of a participant, and then later if the first
5943 /// instance of that participant fails, a new second instance of that
5944 /// participant my be given a token created with AttachToken().
5945 ///
5946 /// If a client uses this message, the client should not rely on the
5947 /// client's own BufferCollectionToken or BufferCollection channel to close
5948 /// from the server end due to abrupt failure of any BufferCollectionToken
5949 /// or BufferCollection that the client has SetDispensable() and given out
5950 /// to another process. For this reason, the client should take extra care
5951 /// to notice failure of that other process via other means.
5952 ///
5953 /// While it is possible (and potentially useful) to SetDispensable() on a
5954 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
5955 /// replace a failed dispensable token that was a direct child of a group
5956 /// with a new token using AttachToken() (since there's no AttachToken() on
5957 /// a group). Instead, to enable AttachToken() replacement in this case,
5958 /// create an additional non-dispensable token (node) that's a direct child
5959 /// of the group and make the existing dispensable token a child of the
5960 /// additional token (node). This way, the additional token (node) that is
5961 /// a direct child of the group has BufferCollection.AttachToken() which can
5962 /// be used to replace the failed dispensable token.
5963 ///
5964 /// SetDispensable() on an already-dispensable token is idempotent.
5965 SetDispensable { control_handle: BufferCollectionTokenControlHandle },
5966 /// Most sysmem clients and many participants don't need to care about this
5967 /// message or about BufferCollectionTokenGroup(s) in general.
5968 ///
5969 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
5970 /// tokens. The child tokens which are not selected during aggregation will
5971 /// fail (close), which a potential participant should notice when their
5972 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
5973 /// participant to clean up the speculative usage that didn't end up
5974 /// happening (similarly to a normal BufferCollection server end closing
5975 /// on failure of a logical buffer collection).
5976 ///
5977 /// See comments on protocol BufferCollectionTokenGroup.
5978 ///
5979 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
5980 /// applied to the whole group can be achieved with a token for this purpose
5981 /// as a direct parent of the group.
5982 ///
5983 /// group_request - the server end of a BufferCollectionTokenGroup channel
5984 /// to be served by sysmem.
5985 CreateBufferCollectionTokenGroup {
5986 group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
5987 control_handle: BufferCollectionTokenControlHandle,
5988 },
5989}
5990
5991impl BufferCollectionTokenRequest {
5992 #[allow(irrefutable_let_patterns)]
5993 pub fn into_sync(self) -> Option<(BufferCollectionTokenSyncResponder)> {
5994 if let BufferCollectionTokenRequest::Sync { responder } = self {
5995 Some((responder))
5996 } else {
5997 None
5998 }
5999 }
6000
6001 #[allow(irrefutable_let_patterns)]
6002 pub fn into_close(self) -> Option<(BufferCollectionTokenControlHandle)> {
6003 if let BufferCollectionTokenRequest::Close { control_handle } = self {
6004 Some((control_handle))
6005 } else {
6006 None
6007 }
6008 }
6009
6010 #[allow(irrefutable_let_patterns)]
6011 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionTokenControlHandle)> {
6012 if let BufferCollectionTokenRequest::SetName { priority, name, control_handle } = self {
6013 Some((priority, name, control_handle))
6014 } else {
6015 None
6016 }
6017 }
6018
6019 #[allow(irrefutable_let_patterns)]
6020 pub fn into_set_debug_client_info(
6021 self,
6022 ) -> Option<(String, u64, BufferCollectionTokenControlHandle)> {
6023 if let BufferCollectionTokenRequest::SetDebugClientInfo { name, id, control_handle } = self
6024 {
6025 Some((name, id, control_handle))
6026 } else {
6027 None
6028 }
6029 }
6030
6031 #[allow(irrefutable_let_patterns)]
6032 pub fn into_set_debug_timeout_log_deadline(
6033 self,
6034 ) -> Option<(i64, BufferCollectionTokenControlHandle)> {
6035 if let BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {
6036 deadline,
6037 control_handle,
6038 } = self
6039 {
6040 Some((deadline, control_handle))
6041 } else {
6042 None
6043 }
6044 }
6045
6046 #[allow(irrefutable_let_patterns)]
6047 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenControlHandle)> {
6048 if let BufferCollectionTokenRequest::SetVerboseLogging { control_handle } = self {
6049 Some((control_handle))
6050 } else {
6051 None
6052 }
6053 }
6054
6055 #[allow(irrefutable_let_patterns)]
6056 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGetNodeRefResponder)> {
6057 if let BufferCollectionTokenRequest::GetNodeRef { responder } = self {
6058 Some((responder))
6059 } else {
6060 None
6061 }
6062 }
6063
6064 #[allow(irrefutable_let_patterns)]
6065 pub fn into_is_alternate_for(
6066 self,
6067 ) -> Option<(fidl::Event, BufferCollectionTokenIsAlternateForResponder)> {
6068 if let BufferCollectionTokenRequest::IsAlternateFor { node_ref, responder } = self {
6069 Some((node_ref, responder))
6070 } else {
6071 None
6072 }
6073 }
6074
6075 #[allow(irrefutable_let_patterns)]
6076 pub fn into_duplicate_sync(
6077 self,
6078 ) -> Option<(Vec<fidl::Rights>, BufferCollectionTokenDuplicateSyncResponder)> {
6079 if let BufferCollectionTokenRequest::DuplicateSync { rights_attenuation_masks, responder } =
6080 self
6081 {
6082 Some((rights_attenuation_masks, responder))
6083 } else {
6084 None
6085 }
6086 }
6087
6088 #[allow(irrefutable_let_patterns)]
6089 pub fn into_duplicate(
6090 self,
6091 ) -> Option<(
6092 u32,
6093 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
6094 BufferCollectionTokenControlHandle,
6095 )> {
6096 if let BufferCollectionTokenRequest::Duplicate {
6097 rights_attenuation_mask,
6098 token_request,
6099 control_handle,
6100 } = self
6101 {
6102 Some((rights_attenuation_mask, token_request, control_handle))
6103 } else {
6104 None
6105 }
6106 }
6107
6108 #[allow(irrefutable_let_patterns)]
6109 pub fn into_set_dispensable(self) -> Option<(BufferCollectionTokenControlHandle)> {
6110 if let BufferCollectionTokenRequest::SetDispensable { control_handle } = self {
6111 Some((control_handle))
6112 } else {
6113 None
6114 }
6115 }
6116
6117 #[allow(irrefutable_let_patterns)]
6118 pub fn into_create_buffer_collection_token_group(
6119 self,
6120 ) -> Option<(
6121 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
6122 BufferCollectionTokenControlHandle,
6123 )> {
6124 if let BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {
6125 group_request,
6126 control_handle,
6127 } = self
6128 {
6129 Some((group_request, control_handle))
6130 } else {
6131 None
6132 }
6133 }
6134
6135 /// Name of the method defined in FIDL
6136 pub fn method_name(&self) -> &'static str {
6137 match *self {
6138 BufferCollectionTokenRequest::Sync { .. } => "sync",
6139 BufferCollectionTokenRequest::Close { .. } => "close",
6140 BufferCollectionTokenRequest::SetName { .. } => "set_name",
6141 BufferCollectionTokenRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
6142 BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline { .. } => {
6143 "set_debug_timeout_log_deadline"
6144 }
6145 BufferCollectionTokenRequest::SetVerboseLogging { .. } => "set_verbose_logging",
6146 BufferCollectionTokenRequest::GetNodeRef { .. } => "get_node_ref",
6147 BufferCollectionTokenRequest::IsAlternateFor { .. } => "is_alternate_for",
6148 BufferCollectionTokenRequest::DuplicateSync { .. } => "duplicate_sync",
6149 BufferCollectionTokenRequest::Duplicate { .. } => "duplicate",
6150 BufferCollectionTokenRequest::SetDispensable { .. } => "set_dispensable",
6151 BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup { .. } => {
6152 "create_buffer_collection_token_group"
6153 }
6154 }
6155 }
6156}
6157
6158#[derive(Debug, Clone)]
6159pub struct BufferCollectionTokenControlHandle {
6160 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
6161}
6162
6163impl fidl::endpoints::ControlHandle for BufferCollectionTokenControlHandle {
6164 fn shutdown(&self) {
6165 self.inner.shutdown()
6166 }
6167 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
6168 self.inner.shutdown_with_epitaph(status)
6169 }
6170
6171 fn is_closed(&self) -> bool {
6172 self.inner.channel().is_closed()
6173 }
6174 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
6175 self.inner.channel().on_closed()
6176 }
6177
6178 #[cfg(target_os = "fuchsia")]
6179 fn signal_peer(
6180 &self,
6181 clear_mask: zx::Signals,
6182 set_mask: zx::Signals,
6183 ) -> Result<(), zx_status::Status> {
6184 use fidl::Peered;
6185 self.inner.channel().signal_peer(clear_mask, set_mask)
6186 }
6187}
6188
6189impl BufferCollectionTokenControlHandle {}
6190
6191#[must_use = "FIDL methods require a response to be sent"]
6192#[derive(Debug)]
6193pub struct BufferCollectionTokenSyncResponder {
6194 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6195 tx_id: u32,
6196}
6197
6198/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6199/// if the responder is dropped without sending a response, so that the client
6200/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6201impl std::ops::Drop for BufferCollectionTokenSyncResponder {
6202 fn drop(&mut self) {
6203 self.control_handle.shutdown();
6204 // Safety: drops once, never accessed again
6205 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6206 }
6207}
6208
6209impl fidl::endpoints::Responder for BufferCollectionTokenSyncResponder {
6210 type ControlHandle = BufferCollectionTokenControlHandle;
6211
6212 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6213 &self.control_handle
6214 }
6215
6216 fn drop_without_shutdown(mut self) {
6217 // Safety: drops once, never accessed again due to mem::forget
6218 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6219 // Prevent Drop from running (which would shut down the channel)
6220 std::mem::forget(self);
6221 }
6222}
6223
6224impl BufferCollectionTokenSyncResponder {
6225 /// Sends a response to the FIDL transaction.
6226 ///
6227 /// Sets the channel to shutdown if an error occurs.
6228 pub fn send(self) -> Result<(), fidl::Error> {
6229 let _result = self.send_raw();
6230 if _result.is_err() {
6231 self.control_handle.shutdown();
6232 }
6233 self.drop_without_shutdown();
6234 _result
6235 }
6236
6237 /// Similar to "send" but does not shutdown the channel if an error occurs.
6238 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
6239 let _result = self.send_raw();
6240 self.drop_without_shutdown();
6241 _result
6242 }
6243
6244 fn send_raw(&self) -> Result<(), fidl::Error> {
6245 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
6246 (),
6247 self.tx_id,
6248 0x4577e238ae26291,
6249 fidl::encoding::DynamicFlags::empty(),
6250 )
6251 }
6252}
6253
6254#[must_use = "FIDL methods require a response to be sent"]
6255#[derive(Debug)]
6256pub struct BufferCollectionTokenGetNodeRefResponder {
6257 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6258 tx_id: u32,
6259}
6260
6261/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6262/// if the responder is dropped without sending a response, so that the client
6263/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6264impl std::ops::Drop for BufferCollectionTokenGetNodeRefResponder {
6265 fn drop(&mut self) {
6266 self.control_handle.shutdown();
6267 // Safety: drops once, never accessed again
6268 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6269 }
6270}
6271
6272impl fidl::endpoints::Responder for BufferCollectionTokenGetNodeRefResponder {
6273 type ControlHandle = BufferCollectionTokenControlHandle;
6274
6275 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6276 &self.control_handle
6277 }
6278
6279 fn drop_without_shutdown(mut self) {
6280 // Safety: drops once, never accessed again due to mem::forget
6281 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6282 // Prevent Drop from running (which would shut down the channel)
6283 std::mem::forget(self);
6284 }
6285}
6286
6287impl BufferCollectionTokenGetNodeRefResponder {
6288 /// Sends a response to the FIDL transaction.
6289 ///
6290 /// Sets the channel to shutdown if an error occurs.
6291 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6292 let _result = self.send_raw(node_ref);
6293 if _result.is_err() {
6294 self.control_handle.shutdown();
6295 }
6296 self.drop_without_shutdown();
6297 _result
6298 }
6299
6300 /// Similar to "send" but does not shutdown the channel if an error occurs.
6301 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6302 let _result = self.send_raw(node_ref);
6303 self.drop_without_shutdown();
6304 _result
6305 }
6306
6307 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6308 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
6309 (node_ref,),
6310 self.tx_id,
6311 0x467b7c75c35c3b84,
6312 fidl::encoding::DynamicFlags::empty(),
6313 )
6314 }
6315}
6316
6317#[must_use = "FIDL methods require a response to be sent"]
6318#[derive(Debug)]
6319pub struct BufferCollectionTokenIsAlternateForResponder {
6320 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6321 tx_id: u32,
6322}
6323
6324/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6325/// if the responder is dropped without sending a response, so that the client
6326/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6327impl std::ops::Drop for BufferCollectionTokenIsAlternateForResponder {
6328 fn drop(&mut self) {
6329 self.control_handle.shutdown();
6330 // Safety: drops once, never accessed again
6331 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6332 }
6333}
6334
6335impl fidl::endpoints::Responder for BufferCollectionTokenIsAlternateForResponder {
6336 type ControlHandle = BufferCollectionTokenControlHandle;
6337
6338 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6339 &self.control_handle
6340 }
6341
6342 fn drop_without_shutdown(mut self) {
6343 // Safety: drops once, never accessed again due to mem::forget
6344 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6345 // Prevent Drop from running (which would shut down the channel)
6346 std::mem::forget(self);
6347 }
6348}
6349
6350impl BufferCollectionTokenIsAlternateForResponder {
6351 /// Sends a response to the FIDL transaction.
6352 ///
6353 /// Sets the channel to shutdown if an error occurs.
6354 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6355 let _result = self.send_raw(result);
6356 if _result.is_err() {
6357 self.control_handle.shutdown();
6358 }
6359 self.drop_without_shutdown();
6360 _result
6361 }
6362
6363 /// Similar to "send" but does not shutdown the channel if an error occurs.
6364 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6365 let _result = self.send_raw(result);
6366 self.drop_without_shutdown();
6367 _result
6368 }
6369
6370 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6371 self.control_handle
6372 .inner
6373 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
6374 result.map(|is_alternate| (is_alternate,)),
6375 self.tx_id,
6376 0x33a2a7aff2776c07,
6377 fidl::encoding::DynamicFlags::empty(),
6378 )
6379 }
6380}
6381
6382#[must_use = "FIDL methods require a response to be sent"]
6383#[derive(Debug)]
6384pub struct BufferCollectionTokenDuplicateSyncResponder {
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 BufferCollectionTokenDuplicateSyncResponder {
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 BufferCollectionTokenDuplicateSyncResponder {
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 BufferCollectionTokenDuplicateSyncResponder {
6416 /// Sends a response to the FIDL transaction.
6417 ///
6418 /// Sets the channel to shutdown if an error occurs.
6419 pub fn send(
6420 self,
6421 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6422 ) -> Result<(), fidl::Error> {
6423 let _result = self.send_raw(tokens);
6424 if _result.is_err() {
6425 self.control_handle.shutdown();
6426 }
6427 self.drop_without_shutdown();
6428 _result
6429 }
6430
6431 /// Similar to "send" but does not shutdown the channel if an error occurs.
6432 pub fn send_no_shutdown_on_err(
6433 self,
6434 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6435 ) -> Result<(), fidl::Error> {
6436 let _result = self.send_raw(tokens);
6437 self.drop_without_shutdown();
6438 _result
6439 }
6440
6441 fn send_raw(
6442 &self,
6443 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6444 ) -> Result<(), fidl::Error> {
6445 self.control_handle.inner.send::<BufferCollectionTokenDuplicateSyncResponse>(
6446 (tokens.as_mut(),),
6447 self.tx_id,
6448 0x49ed7ab7cc19f18,
6449 fidl::encoding::DynamicFlags::empty(),
6450 )
6451 }
6452}
6453
6454#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
6455pub struct BufferCollectionTokenGroupMarker;
6456
6457impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenGroupMarker {
6458 type Proxy = BufferCollectionTokenGroupProxy;
6459 type RequestStream = BufferCollectionTokenGroupRequestStream;
6460 #[cfg(target_os = "fuchsia")]
6461 type SynchronousProxy = BufferCollectionTokenGroupSynchronousProxy;
6462
6463 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionTokenGroup";
6464}
6465
6466pub trait BufferCollectionTokenGroupProxyInterface: Send + Sync {
6467 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
6468 fn r#sync(&self) -> Self::SyncResponseFut;
6469 fn r#close(&self) -> Result<(), fidl::Error>;
6470 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
6471 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
6472 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
6473 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
6474 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
6475 + Send;
6476 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
6477 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
6478 + Send;
6479 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
6480 fn r#create_child(
6481 &self,
6482 payload: BufferCollectionTokenGroupCreateChildRequest,
6483 ) -> Result<(), fidl::Error>;
6484 type CreateChildrenSyncResponseFut: std::future::Future<
6485 Output = Result<
6486 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6487 fidl::Error,
6488 >,
6489 > + Send;
6490 fn r#create_children_sync(
6491 &self,
6492 rights_attenuation_masks: &[fidl::Rights],
6493 ) -> Self::CreateChildrenSyncResponseFut;
6494 fn r#all_children_present(&self) -> Result<(), fidl::Error>;
6495}
6496#[derive(Debug)]
6497#[cfg(target_os = "fuchsia")]
6498pub struct BufferCollectionTokenGroupSynchronousProxy {
6499 client: fidl::client::sync::Client,
6500}
6501
6502#[cfg(target_os = "fuchsia")]
6503impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenGroupSynchronousProxy {
6504 type Proxy = BufferCollectionTokenGroupProxy;
6505 type Protocol = BufferCollectionTokenGroupMarker;
6506
6507 fn from_channel(inner: fidl::Channel) -> Self {
6508 Self::new(inner)
6509 }
6510
6511 fn into_channel(self) -> fidl::Channel {
6512 self.client.into_channel()
6513 }
6514
6515 fn as_channel(&self) -> &fidl::Channel {
6516 self.client.as_channel()
6517 }
6518}
6519
6520#[cfg(target_os = "fuchsia")]
6521impl BufferCollectionTokenGroupSynchronousProxy {
6522 pub fn new(channel: fidl::Channel) -> Self {
6523 let protocol_name =
6524 <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
6525 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
6526 }
6527
6528 pub fn into_channel(self) -> fidl::Channel {
6529 self.client.into_channel()
6530 }
6531
6532 /// Waits until an event arrives and returns it. It is safe for other
6533 /// threads to make concurrent requests while waiting for an event.
6534 pub fn wait_for_event(
6535 &self,
6536 deadline: zx::MonotonicInstant,
6537 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
6538 BufferCollectionTokenGroupEvent::decode(self.client.wait_for_event(deadline)?)
6539 }
6540
6541 /// Ensure that previous messages, including Duplicate() messages on a
6542 /// token, collection, or group, have been received server side.
6543 ///
6544 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
6545 /// valid sysmem token risks the Sync() hanging forever. See
6546 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
6547 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
6548 /// Another way is to pass the token to BindSharedCollection(), which also
6549 /// validates the token as part of exchanging it for a BufferCollection
6550 /// channel, and BufferCollection Sync() can then be used.
6551 ///
6552 /// After a Sync(), it's then safe to send the client end of token_request
6553 /// to another participant knowing the server will recognize the token when
6554 /// it's sent into BindSharedCollection() by the other participant.
6555 ///
6556 /// Other options include waiting for each token.Duplicate() to complete
6557 /// individually (using separate call to token.Sync() after each), or
6558 /// calling Sync() on BufferCollection after the token has been turned in
6559 /// via BindSharedCollection().
6560 ///
6561 /// Another way to mitigate is to avoid calling Sync() on the token, and
6562 /// instead later deal with potential failure of BufferCollection.Sync() if
6563 /// the original token was invalid. This option can be preferable from a
6564 /// performance point of view, but requires client code to delay sending
6565 /// tokens duplicated from this token until after client code has converted
6566 /// the duplicating token to a BufferCollection and received successful
6567 /// response from BufferCollection.Sync().
6568 ///
6569 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
6570 /// When BufferCollection.Sync() isn't feasible, the caller must already
6571 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
6572 /// hang forever. See ValidateBufferCollectionToken() to check token
6573 /// validity first if the token isn't already known to be (is/was) valid.
6574 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
6575 let _response =
6576 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
6577 (),
6578 0x4577e238ae26291,
6579 fidl::encoding::DynamicFlags::empty(),
6580 ___deadline,
6581 )?;
6582 Ok(_response)
6583 }
6584
6585 /// On a BufferCollectionToken channel:
6586 ///
6587 /// Normally a participant will convert a BufferCollectionToken into a
6588 /// BufferCollection view, but a participant is also free to Close() the
6589 /// token (and then close the channel immediately or shortly later in
6590 /// response to server closing its end), which avoids causing logical buffer
6591 /// collection failure. Â Normally an unexpected token channel close will
6592 /// cause logical buffer collection failure (the only exceptions being
6593 /// certain cases involving AttachToken() or SetDispensable()).
6594 ///
6595 /// On a BufferCollection channel:
6596 ///
6597 /// By default the server handles unexpected failure of a BufferCollection
6598 /// by failing the whole logical buffer collection. Partly this is to
6599 /// expedite closing VMO handles to reclaim memory when any participant
6600 /// fails. If a participant would like to cleanly close a BufferCollection
6601 /// view without causing logical buffer collection failure, the participant
6602 /// can send Close() before closing the client end of the BufferCollection
6603 /// channel. If this is the last BufferCollection view, the logical buffer
6604 /// collection will still go away. The Close() can occur before or after
6605 /// SetConstraints(). If before SetConstraints(), the buffer collection
6606 /// won't require constraints from this node in order to allocate. If
6607 /// after SetConstraints(), the constraints are retained and aggregated
6608 /// along with any subsequent logical allocation(s), despite the lack of
6609 /// channel connection.
6610 ///
6611 /// On a BufferCollectionTokenGroup channel:
6612 ///
6613 /// By default, unexpected failure of a BufferCollectionTokenGroup will
6614 /// trigger failure of the logical BufferCollectionTokenGroup and will
6615 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
6616 /// channel without failing the logical group or propagating failure, send
6617 /// Close() before closing the channel client endpoint.
6618 ///
6619 /// If Close() occurs before AllChildrenPresent(), the logical buffer
6620 /// collection will still fail despite the Close() (because sysmem can't be
6621 /// sure whether all relevant children were created, so it's ambiguous
6622 /// whether all relevant constraints will be provided to sysmem). If
6623 /// Close() occurs after AllChildrenPresent(), the children and all their
6624 /// constraints remain intact (just as they would if the
6625 /// BufferCollectionTokenGroup channel had remained open), and the close
6626 /// doesn't trigger or propagate failure.
6627 pub fn r#close(&self) -> Result<(), fidl::Error> {
6628 self.client.send::<fidl::encoding::EmptyPayload>(
6629 (),
6630 0x5b1d7a4f5681fca7,
6631 fidl::encoding::DynamicFlags::empty(),
6632 )
6633 }
6634
6635 /// Set a name for VMOs in this buffer collection. The name may be truncated
6636 /// shorter. The name only affects VMOs allocated after it's set - this call
6637 /// does not rename existing VMOs. If multiple clients set different names
6638 /// then the larger priority value will win.
6639 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
6640 self.client.send::<NodeSetNameRequest>(
6641 (priority, name),
6642 0x77a41bb6217e2443,
6643 fidl::encoding::DynamicFlags::empty(),
6644 )
6645 }
6646
6647 /// Set information about the current client that can be used by sysmem to
6648 /// help debug leaking memory and hangs waiting for constraints. |name| can
6649 /// be an arbitrary string, but the current process name (see
6650 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
6651 /// arbitrary id, but the current process ID (see
6652 /// fsl::GetCurrentProcessKoid()) is a good default.
6653 ///
6654 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
6655 /// indicate which client is closing their channel first, leading to
6656 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
6657 /// over, but if happening earlier than expected, the
6658 /// client-channel-specific name can help diagnose where the failure is
6659 /// first coming from, from sysmem's point of view).
6660 ///
6661 /// By default (unless overriden by this message or using
6662 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
6663 /// parent Node at the time the child Node is created. While this can be
6664 /// better than nothing, it's often better for each participant to use
6665 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
6666 /// info directly relevant to the current client. Also, SetVerboseLogging()
6667 /// can be used to help disambiguate if a Node is suspected of having info
6668 /// that was copied from its parent.
6669 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
6670 self.client.send::<NodeSetDebugClientInfoRequest>(
6671 (name, id),
6672 0x7275759070eb5ee2,
6673 fidl::encoding::DynamicFlags::empty(),
6674 )
6675 }
6676
6677 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
6678 /// after creating a collection. Clients can call this method to change
6679 /// when the log is printed. If multiple client set the deadline, it's
6680 /// unspecified which deadline will take effect.
6681 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
6682 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
6683 (deadline,),
6684 0x46d38f4772638867,
6685 fidl::encoding::DynamicFlags::empty(),
6686 )
6687 }
6688
6689 /// Verbose logging includes constraints set via SetConstraints() from each
6690 /// client along with info set via SetDebugClientInfo() and the structure of
6691 /// the tree of Node(s).
6692 ///
6693 /// Normally sysmem prints only a single line complaint when aggregation
6694 /// fails, with just the specific detailed reason that aggregation failed,
6695 /// with minimal context. While this is often enough to diagnose a problem
6696 /// if only a small change was made and the system had been working before
6697 /// the small change, it's often not particularly helpful for getting a new
6698 /// buffer collection to work for the first time. Especially with more
6699 /// complex trees of nodes, involving things like AttachToken(),
6700 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
6701 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
6702 /// looks like and why it's failing a logical allocation, or why a tree or
6703 /// sub-tree is failing sooner than expected.
6704 ///
6705 /// The intent of the extra logging is to be acceptable from a performance
6706 /// point of view, if only enabled on a low number of buffer collections.
6707 /// If we're not tracking down a bug, we shouldn't send this message.
6708 ///
6709 /// If too many participants leave verbose logging enabled, we may end up
6710 /// needing to require that system-wide sysmem verbose logging be permitted
6711 /// via some other setting, to avoid sysmem spamming the log too much due to
6712 /// this message.
6713 ///
6714 /// This may be a NOP for some nodes due to intentional policy associated
6715 /// with the node, if we don't trust a node enough to let it turn on verbose
6716 /// logging.
6717 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
6718 self.client.send::<fidl::encoding::EmptyPayload>(
6719 (),
6720 0x6bfbe2cf1701d288,
6721 fidl::encoding::DynamicFlags::empty(),
6722 )
6723 }
6724
6725 /// This gets an event handle that can be used as a parameter to
6726 /// IsAlternateFor() called on any Node. The client will not be granted the
6727 /// right to signal this event, as this handle should only be used as proof
6728 /// that the client obtained this handle from this Node.
6729 ///
6730 /// Because this is a get not a set, no Sync() is needed between the
6731 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
6732 /// potentially being on different channels.
6733 ///
6734 /// See also IsAlternateFor().
6735 pub fn r#get_node_ref(
6736 &self,
6737 ___deadline: zx::MonotonicInstant,
6738 ) -> Result<fidl::Event, fidl::Error> {
6739 let _response =
6740 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
6741 (),
6742 0x467b7c75c35c3b84,
6743 fidl::encoding::DynamicFlags::empty(),
6744 ___deadline,
6745 )?;
6746 Ok(_response.node_ref)
6747 }
6748
6749 /// This checks whether the calling node is in a subtree rooted at a
6750 /// different child token of a common parent BufferCollectionTokenGroup, in
6751 /// relation to the passed-in node_ref.
6752 ///
6753 /// This call is for assisting with admission control de-duplication, and
6754 /// with debugging.
6755 ///
6756 /// The node_ref must be obtained using GetNodeRef() of a
6757 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
6758 ///
6759 /// The node_ref can be a duplicated handle; it's not necessary to call
6760 /// GetNodeRef() for every call to IsAlternateFor().
6761 ///
6762 /// If a calling token may not actually be a valid token at all due to
6763 /// a potentially hostile/untrusted provider of the token, call
6764 /// ValidateBufferCollectionToken() first instead of potentially getting
6765 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
6766 /// token not being a real token (not really talking to sysmem). Another
6767 /// option is to call BindSharedCollection with this token first which also
6768 /// validates the token along with converting it to a BufferCollection, then
6769 /// call BufferCollection IsAlternateFor().
6770 ///
6771 /// error values:
6772 ///
6773 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
6774 /// buffer collection as the calling Node. Before logical allocation and
6775 /// within the same logical allocation sub-tree, this essentially means that
6776 /// the node_ref was never part of this logical buffer collection, since
6777 /// before logical allocation all node_refs that come into existence remain
6778 /// in existence at least until logical allocation (including Node(s) that
6779 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
6780 /// to be returned, this Node's channel needs to still be connected server
6781 /// side, which won't be the case if the whole logical allocation has
6782 /// failed. After logical allocation or in a different logical allocation
6783 /// sub-tree there are additional potential reasons for this error. For
6784 /// example a different logical allocation (separated from this Node(s)
6785 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
6786 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
6787 /// exist and may select a different child sub-tree than the sub-tree the
6788 /// node_ref is in causing deletion of the node_ref Node. The only time
6789 /// sysmem keeps a Node around after that Node has no corresponding channel
6790 /// is when Close() is used and the Node's sub-tree has not yet failed.
6791 /// Another reason for this error is if the node_ref is an eventpair handle
6792 /// with sufficient rights, but isn't actually a real node_ref obtained from
6793 /// GetNodeRef().
6794 ///
6795 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
6796 /// eventpair handle, or doesn't have the needed rights expected on a real
6797 /// node_ref.
6798 ///
6799 /// No other failing status codes are returned by this call. However,
6800 /// sysmem may add additional codes in future, so the client should have
6801 /// sensible default handling for any failing status code.
6802 ///
6803 /// On success, is_alternate has the following meaning:
6804 /// * true - The first parent node in common between the calling node and
6805 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
6806 /// the calling Node and the node_ref Node will _not_ have both their
6807 /// constraints apply - rather sysmem will choose one or the other of
6808 /// the constraints - never both. This is because only one child of
6809 /// a BufferCollectionTokenGroup is selected during logical allocation,
6810 /// with only that one child's sub-tree contributing to constraints
6811 /// aggregation.
6812 /// * false - The first parent node in common between the calling Node and
6813 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
6814 /// this means the first parent node in common is a
6815 /// BufferCollectionToken or BufferCollection (regardless of not
6816 /// Close()ed or Close()ed). This means that the calling Node and the
6817 /// node_ref Node _may_ have both their constraints apply during
6818 /// constraints aggregation of the logical allocation, if both Node(s)
6819 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
6820 /// In this case, there is no BufferCollectionTokenGroup that will
6821 /// directly prevent the two Node(s) from both being selected and their
6822 /// constraints both aggregated, but even when false, one or both
6823 /// Node(s) may still be eliminated from consideration if one or both
6824 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
6825 /// which selects a child sub-tree other than the sub-tree containing
6826 /// the calling Node or node_ref Node.
6827 pub fn r#is_alternate_for(
6828 &self,
6829 mut node_ref: fidl::Event,
6830 ___deadline: zx::MonotonicInstant,
6831 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
6832 let _response = self.client.send_query::<
6833 NodeIsAlternateForRequest,
6834 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
6835 >(
6836 (node_ref,),
6837 0x33a2a7aff2776c07,
6838 fidl::encoding::DynamicFlags::empty(),
6839 ___deadline,
6840 )?;
6841 Ok(_response.map(|x| x.is_alternate))
6842 }
6843
6844 /// Create a child token. Before passing the client end of this token to
6845 /// BindSharedCollection(), completion of Sync() after CreateChild() is
6846 /// required. Or the client can use CreateChildrenSync() which essentially
6847 /// includes the Sync().
6848 ///
6849 /// token_request - the server end of the new token channel.
6850 ///
6851 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
6852 /// allows the holder to get the same rights to buffers as the parent token
6853 /// (of the group) had.
6854 pub fn r#create_child(
6855 &self,
6856 mut payload: BufferCollectionTokenGroupCreateChildRequest,
6857 ) -> Result<(), fidl::Error> {
6858 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
6859 &mut payload,
6860 0x2e74f8bcbf59ee59,
6861 fidl::encoding::DynamicFlags::empty(),
6862 )
6863 }
6864
6865 /// Create 1 or more child tokens at once, synchronously. In contrast to
6866 /// CreateChild(), no Sync() completion is required before passing the
6867 /// client end of a returned token to BindSharedCollection().
6868 ///
6869 /// The size of the rights_attentuation_mask determines the number of
6870 /// created child tokens.
6871 ///
6872 /// The lower-index child tokens are higher priority (attempted sooner) than
6873 /// higher-index child tokens.
6874 ///
6875 /// As per all child tokens, successful aggregation will choose exactly one
6876 /// child among all created children (across all children created across
6877 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
6878 ///
6879 /// The maximum permissible total number of children per group, and total
6880 /// number of nodes in an overall tree (from the root) are capped to limits
6881 /// which are not configurable via these protocols.
6882 pub fn r#create_children_sync(
6883 &self,
6884 mut rights_attenuation_masks: &[fidl::Rights],
6885 ___deadline: zx::MonotonicInstant,
6886 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error> {
6887 let _response = self.client.send_query::<
6888 BufferCollectionTokenGroupCreateChildrenSyncRequest,
6889 BufferCollectionTokenGroupCreateChildrenSyncResponse,
6890 >(
6891 (rights_attenuation_masks,),
6892 0x569dc3ca2a98f535,
6893 fidl::encoding::DynamicFlags::empty(),
6894 ___deadline,
6895 )?;
6896 Ok(_response.tokens)
6897 }
6898
6899 /// AllChildrenPresent()
6900 ///
6901 /// After creating all children, the client must call AllChildrenPresent()
6902 /// to inform sysmem that no more children will be created, so that sysmem
6903 /// can know when it's ok to start aggregating constraints.
6904 ///
6905 /// If Close() is to be sent, it should be sent _after_
6906 /// AllChildrenPresent(), else failure of the group and propagation of the
6907 /// failure to the group's parent will still be triggered.
6908 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
6909 self.client.send::<fidl::encoding::EmptyPayload>(
6910 (),
6911 0x1d41715f6f044b50,
6912 fidl::encoding::DynamicFlags::empty(),
6913 )
6914 }
6915}
6916
6917#[cfg(target_os = "fuchsia")]
6918impl From<BufferCollectionTokenGroupSynchronousProxy> for zx::Handle {
6919 fn from(value: BufferCollectionTokenGroupSynchronousProxy) -> Self {
6920 value.into_channel().into()
6921 }
6922}
6923
6924#[cfg(target_os = "fuchsia")]
6925impl From<fidl::Channel> for BufferCollectionTokenGroupSynchronousProxy {
6926 fn from(value: fidl::Channel) -> Self {
6927 Self::new(value)
6928 }
6929}
6930
6931#[cfg(target_os = "fuchsia")]
6932impl fidl::endpoints::FromClient for BufferCollectionTokenGroupSynchronousProxy {
6933 type Protocol = BufferCollectionTokenGroupMarker;
6934
6935 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionTokenGroupMarker>) -> Self {
6936 Self::new(value.into_channel())
6937 }
6938}
6939
6940#[derive(Debug, Clone)]
6941pub struct BufferCollectionTokenGroupProxy {
6942 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
6943}
6944
6945impl fidl::endpoints::Proxy for BufferCollectionTokenGroupProxy {
6946 type Protocol = BufferCollectionTokenGroupMarker;
6947
6948 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
6949 Self::new(inner)
6950 }
6951
6952 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
6953 self.client.into_channel().map_err(|client| Self { client })
6954 }
6955
6956 fn as_channel(&self) -> &::fidl::AsyncChannel {
6957 self.client.as_channel()
6958 }
6959}
6960
6961impl BufferCollectionTokenGroupProxy {
6962 /// Create a new Proxy for fuchsia.sysmem/BufferCollectionTokenGroup.
6963 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
6964 let protocol_name =
6965 <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
6966 Self { client: fidl::client::Client::new(channel, protocol_name) }
6967 }
6968
6969 /// Get a Stream of events from the remote end of the protocol.
6970 ///
6971 /// # Panics
6972 ///
6973 /// Panics if the event stream was already taken.
6974 pub fn take_event_stream(&self) -> BufferCollectionTokenGroupEventStream {
6975 BufferCollectionTokenGroupEventStream { event_receiver: self.client.take_event_receiver() }
6976 }
6977
6978 /// Ensure that previous messages, including Duplicate() messages on a
6979 /// token, collection, or group, have been received server side.
6980 ///
6981 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
6982 /// valid sysmem token risks the Sync() hanging forever. See
6983 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
6984 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
6985 /// Another way is to pass the token to BindSharedCollection(), which also
6986 /// validates the token as part of exchanging it for a BufferCollection
6987 /// channel, and BufferCollection Sync() can then be used.
6988 ///
6989 /// After a Sync(), it's then safe to send the client end of token_request
6990 /// to another participant knowing the server will recognize the token when
6991 /// it's sent into BindSharedCollection() by the other participant.
6992 ///
6993 /// Other options include waiting for each token.Duplicate() to complete
6994 /// individually (using separate call to token.Sync() after each), or
6995 /// calling Sync() on BufferCollection after the token has been turned in
6996 /// via BindSharedCollection().
6997 ///
6998 /// Another way to mitigate is to avoid calling Sync() on the token, and
6999 /// instead later deal with potential failure of BufferCollection.Sync() if
7000 /// the original token was invalid. This option can be preferable from a
7001 /// performance point of view, but requires client code to delay sending
7002 /// tokens duplicated from this token until after client code has converted
7003 /// the duplicating token to a BufferCollection and received successful
7004 /// response from BufferCollection.Sync().
7005 ///
7006 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
7007 /// When BufferCollection.Sync() isn't feasible, the caller must already
7008 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
7009 /// hang forever. See ValidateBufferCollectionToken() to check token
7010 /// validity first if the token isn't already known to be (is/was) valid.
7011 pub fn r#sync(
7012 &self,
7013 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
7014 BufferCollectionTokenGroupProxyInterface::r#sync(self)
7015 }
7016
7017 /// On a BufferCollectionToken channel:
7018 ///
7019 /// Normally a participant will convert a BufferCollectionToken into a
7020 /// BufferCollection view, but a participant is also free to Close() the
7021 /// token (and then close the channel immediately or shortly later in
7022 /// response to server closing its end), which avoids causing logical buffer
7023 /// collection failure. Â Normally an unexpected token channel close will
7024 /// cause logical buffer collection failure (the only exceptions being
7025 /// certain cases involving AttachToken() or SetDispensable()).
7026 ///
7027 /// On a BufferCollection channel:
7028 ///
7029 /// By default the server handles unexpected failure of a BufferCollection
7030 /// by failing the whole logical buffer collection. Partly this is to
7031 /// expedite closing VMO handles to reclaim memory when any participant
7032 /// fails. If a participant would like to cleanly close a BufferCollection
7033 /// view without causing logical buffer collection failure, the participant
7034 /// can send Close() before closing the client end of the BufferCollection
7035 /// channel. If this is the last BufferCollection view, the logical buffer
7036 /// collection will still go away. The Close() can occur before or after
7037 /// SetConstraints(). If before SetConstraints(), the buffer collection
7038 /// won't require constraints from this node in order to allocate. If
7039 /// after SetConstraints(), the constraints are retained and aggregated
7040 /// along with any subsequent logical allocation(s), despite the lack of
7041 /// channel connection.
7042 ///
7043 /// On a BufferCollectionTokenGroup channel:
7044 ///
7045 /// By default, unexpected failure of a BufferCollectionTokenGroup will
7046 /// trigger failure of the logical BufferCollectionTokenGroup and will
7047 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
7048 /// channel without failing the logical group or propagating failure, send
7049 /// Close() before closing the channel client endpoint.
7050 ///
7051 /// If Close() occurs before AllChildrenPresent(), the logical buffer
7052 /// collection will still fail despite the Close() (because sysmem can't be
7053 /// sure whether all relevant children were created, so it's ambiguous
7054 /// whether all relevant constraints will be provided to sysmem). If
7055 /// Close() occurs after AllChildrenPresent(), the children and all their
7056 /// constraints remain intact (just as they would if the
7057 /// BufferCollectionTokenGroup channel had remained open), and the close
7058 /// doesn't trigger or propagate failure.
7059 pub fn r#close(&self) -> Result<(), fidl::Error> {
7060 BufferCollectionTokenGroupProxyInterface::r#close(self)
7061 }
7062
7063 /// Set a name for VMOs in this buffer collection. The name may be truncated
7064 /// shorter. The name only affects VMOs allocated after it's set - this call
7065 /// does not rename existing VMOs. If multiple clients set different names
7066 /// then the larger priority value will win.
7067 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
7068 BufferCollectionTokenGroupProxyInterface::r#set_name(self, priority, name)
7069 }
7070
7071 /// Set information about the current client that can be used by sysmem to
7072 /// help debug leaking memory and hangs waiting for constraints. |name| can
7073 /// be an arbitrary string, but the current process name (see
7074 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
7075 /// arbitrary id, but the current process ID (see
7076 /// fsl::GetCurrentProcessKoid()) is a good default.
7077 ///
7078 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
7079 /// indicate which client is closing their channel first, leading to
7080 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
7081 /// over, but if happening earlier than expected, the
7082 /// client-channel-specific name can help diagnose where the failure is
7083 /// first coming from, from sysmem's point of view).
7084 ///
7085 /// By default (unless overriden by this message or using
7086 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
7087 /// parent Node at the time the child Node is created. While this can be
7088 /// better than nothing, it's often better for each participant to use
7089 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
7090 /// info directly relevant to the current client. Also, SetVerboseLogging()
7091 /// can be used to help disambiguate if a Node is suspected of having info
7092 /// that was copied from its parent.
7093 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
7094 BufferCollectionTokenGroupProxyInterface::r#set_debug_client_info(self, name, id)
7095 }
7096
7097 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
7098 /// after creating a collection. Clients can call this method to change
7099 /// when the log is printed. If multiple client set the deadline, it's
7100 /// unspecified which deadline will take effect.
7101 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
7102 BufferCollectionTokenGroupProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
7103 }
7104
7105 /// Verbose logging includes constraints set via SetConstraints() from each
7106 /// client along with info set via SetDebugClientInfo() and the structure of
7107 /// the tree of Node(s).
7108 ///
7109 /// Normally sysmem prints only a single line complaint when aggregation
7110 /// fails, with just the specific detailed reason that aggregation failed,
7111 /// with minimal context. While this is often enough to diagnose a problem
7112 /// if only a small change was made and the system had been working before
7113 /// the small change, it's often not particularly helpful for getting a new
7114 /// buffer collection to work for the first time. Especially with more
7115 /// complex trees of nodes, involving things like AttachToken(),
7116 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
7117 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
7118 /// looks like and why it's failing a logical allocation, or why a tree or
7119 /// sub-tree is failing sooner than expected.
7120 ///
7121 /// The intent of the extra logging is to be acceptable from a performance
7122 /// point of view, if only enabled on a low number of buffer collections.
7123 /// If we're not tracking down a bug, we shouldn't send this message.
7124 ///
7125 /// If too many participants leave verbose logging enabled, we may end up
7126 /// needing to require that system-wide sysmem verbose logging be permitted
7127 /// via some other setting, to avoid sysmem spamming the log too much due to
7128 /// this message.
7129 ///
7130 /// This may be a NOP for some nodes due to intentional policy associated
7131 /// with the node, if we don't trust a node enough to let it turn on verbose
7132 /// logging.
7133 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7134 BufferCollectionTokenGroupProxyInterface::r#set_verbose_logging(self)
7135 }
7136
7137 /// This gets an event handle that can be used as a parameter to
7138 /// IsAlternateFor() called on any Node. The client will not be granted the
7139 /// right to signal this event, as this handle should only be used as proof
7140 /// that the client obtained this handle from this Node.
7141 ///
7142 /// Because this is a get not a set, no Sync() is needed between the
7143 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
7144 /// potentially being on different channels.
7145 ///
7146 /// See also IsAlternateFor().
7147 pub fn r#get_node_ref(
7148 &self,
7149 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
7150 {
7151 BufferCollectionTokenGroupProxyInterface::r#get_node_ref(self)
7152 }
7153
7154 /// This checks whether the calling node is in a subtree rooted at a
7155 /// different child token of a common parent BufferCollectionTokenGroup, in
7156 /// relation to the passed-in node_ref.
7157 ///
7158 /// This call is for assisting with admission control de-duplication, and
7159 /// with debugging.
7160 ///
7161 /// The node_ref must be obtained using GetNodeRef() of a
7162 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
7163 ///
7164 /// The node_ref can be a duplicated handle; it's not necessary to call
7165 /// GetNodeRef() for every call to IsAlternateFor().
7166 ///
7167 /// If a calling token may not actually be a valid token at all due to
7168 /// a potentially hostile/untrusted provider of the token, call
7169 /// ValidateBufferCollectionToken() first instead of potentially getting
7170 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
7171 /// token not being a real token (not really talking to sysmem). Another
7172 /// option is to call BindSharedCollection with this token first which also
7173 /// validates the token along with converting it to a BufferCollection, then
7174 /// call BufferCollection IsAlternateFor().
7175 ///
7176 /// error values:
7177 ///
7178 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
7179 /// buffer collection as the calling Node. Before logical allocation and
7180 /// within the same logical allocation sub-tree, this essentially means that
7181 /// the node_ref was never part of this logical buffer collection, since
7182 /// before logical allocation all node_refs that come into existence remain
7183 /// in existence at least until logical allocation (including Node(s) that
7184 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
7185 /// to be returned, this Node's channel needs to still be connected server
7186 /// side, which won't be the case if the whole logical allocation has
7187 /// failed. After logical allocation or in a different logical allocation
7188 /// sub-tree there are additional potential reasons for this error. For
7189 /// example a different logical allocation (separated from this Node(s)
7190 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
7191 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
7192 /// exist and may select a different child sub-tree than the sub-tree the
7193 /// node_ref is in causing deletion of the node_ref Node. The only time
7194 /// sysmem keeps a Node around after that Node has no corresponding channel
7195 /// is when Close() is used and the Node's sub-tree has not yet failed.
7196 /// Another reason for this error is if the node_ref is an eventpair handle
7197 /// with sufficient rights, but isn't actually a real node_ref obtained from
7198 /// GetNodeRef().
7199 ///
7200 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
7201 /// eventpair handle, or doesn't have the needed rights expected on a real
7202 /// node_ref.
7203 ///
7204 /// No other failing status codes are returned by this call. However,
7205 /// sysmem may add additional codes in future, so the client should have
7206 /// sensible default handling for any failing status code.
7207 ///
7208 /// On success, is_alternate has the following meaning:
7209 /// * true - The first parent node in common between the calling node and
7210 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
7211 /// the calling Node and the node_ref Node will _not_ have both their
7212 /// constraints apply - rather sysmem will choose one or the other of
7213 /// the constraints - never both. This is because only one child of
7214 /// a BufferCollectionTokenGroup is selected during logical allocation,
7215 /// with only that one child's sub-tree contributing to constraints
7216 /// aggregation.
7217 /// * false - The first parent node in common between the calling Node and
7218 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
7219 /// this means the first parent node in common is a
7220 /// BufferCollectionToken or BufferCollection (regardless of not
7221 /// Close()ed or Close()ed). This means that the calling Node and the
7222 /// node_ref Node _may_ have both their constraints apply during
7223 /// constraints aggregation of the logical allocation, if both Node(s)
7224 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
7225 /// In this case, there is no BufferCollectionTokenGroup that will
7226 /// directly prevent the two Node(s) from both being selected and their
7227 /// constraints both aggregated, but even when false, one or both
7228 /// Node(s) may still be eliminated from consideration if one or both
7229 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
7230 /// which selects a child sub-tree other than the sub-tree containing
7231 /// the calling Node or node_ref Node.
7232 pub fn r#is_alternate_for(
7233 &self,
7234 mut node_ref: fidl::Event,
7235 ) -> fidl::client::QueryResponseFut<
7236 NodeIsAlternateForResult,
7237 fidl::encoding::DefaultFuchsiaResourceDialect,
7238 > {
7239 BufferCollectionTokenGroupProxyInterface::r#is_alternate_for(self, node_ref)
7240 }
7241
7242 /// Create a child token. Before passing the client end of this token to
7243 /// BindSharedCollection(), completion of Sync() after CreateChild() is
7244 /// required. Or the client can use CreateChildrenSync() which essentially
7245 /// includes the Sync().
7246 ///
7247 /// token_request - the server end of the new token channel.
7248 ///
7249 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
7250 /// allows the holder to get the same rights to buffers as the parent token
7251 /// (of the group) had.
7252 pub fn r#create_child(
7253 &self,
7254 mut payload: BufferCollectionTokenGroupCreateChildRequest,
7255 ) -> Result<(), fidl::Error> {
7256 BufferCollectionTokenGroupProxyInterface::r#create_child(self, payload)
7257 }
7258
7259 /// Create 1 or more child tokens at once, synchronously. In contrast to
7260 /// CreateChild(), no Sync() completion is required before passing the
7261 /// client end of a returned token to BindSharedCollection().
7262 ///
7263 /// The size of the rights_attentuation_mask determines the number of
7264 /// created child tokens.
7265 ///
7266 /// The lower-index child tokens are higher priority (attempted sooner) than
7267 /// higher-index child tokens.
7268 ///
7269 /// As per all child tokens, successful aggregation will choose exactly one
7270 /// child among all created children (across all children created across
7271 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
7272 ///
7273 /// The maximum permissible total number of children per group, and total
7274 /// number of nodes in an overall tree (from the root) are capped to limits
7275 /// which are not configurable via these protocols.
7276 pub fn r#create_children_sync(
7277 &self,
7278 mut rights_attenuation_masks: &[fidl::Rights],
7279 ) -> fidl::client::QueryResponseFut<
7280 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7281 fidl::encoding::DefaultFuchsiaResourceDialect,
7282 > {
7283 BufferCollectionTokenGroupProxyInterface::r#create_children_sync(
7284 self,
7285 rights_attenuation_masks,
7286 )
7287 }
7288
7289 /// AllChildrenPresent()
7290 ///
7291 /// After creating all children, the client must call AllChildrenPresent()
7292 /// to inform sysmem that no more children will be created, so that sysmem
7293 /// can know when it's ok to start aggregating constraints.
7294 ///
7295 /// If Close() is to be sent, it should be sent _after_
7296 /// AllChildrenPresent(), else failure of the group and propagation of the
7297 /// failure to the group's parent will still be triggered.
7298 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
7299 BufferCollectionTokenGroupProxyInterface::r#all_children_present(self)
7300 }
7301}
7302
7303impl BufferCollectionTokenGroupProxyInterface for BufferCollectionTokenGroupProxy {
7304 type SyncResponseFut =
7305 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
7306 fn r#sync(&self) -> Self::SyncResponseFut {
7307 fn _decode(
7308 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7309 ) -> Result<(), fidl::Error> {
7310 let _response = fidl::client::decode_transaction_body::<
7311 fidl::encoding::EmptyPayload,
7312 fidl::encoding::DefaultFuchsiaResourceDialect,
7313 0x4577e238ae26291,
7314 >(_buf?)?;
7315 Ok(_response)
7316 }
7317 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
7318 (),
7319 0x4577e238ae26291,
7320 fidl::encoding::DynamicFlags::empty(),
7321 _decode,
7322 )
7323 }
7324
7325 fn r#close(&self) -> Result<(), fidl::Error> {
7326 self.client.send::<fidl::encoding::EmptyPayload>(
7327 (),
7328 0x5b1d7a4f5681fca7,
7329 fidl::encoding::DynamicFlags::empty(),
7330 )
7331 }
7332
7333 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
7334 self.client.send::<NodeSetNameRequest>(
7335 (priority, name),
7336 0x77a41bb6217e2443,
7337 fidl::encoding::DynamicFlags::empty(),
7338 )
7339 }
7340
7341 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
7342 self.client.send::<NodeSetDebugClientInfoRequest>(
7343 (name, id),
7344 0x7275759070eb5ee2,
7345 fidl::encoding::DynamicFlags::empty(),
7346 )
7347 }
7348
7349 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
7350 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
7351 (deadline,),
7352 0x46d38f4772638867,
7353 fidl::encoding::DynamicFlags::empty(),
7354 )
7355 }
7356
7357 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7358 self.client.send::<fidl::encoding::EmptyPayload>(
7359 (),
7360 0x6bfbe2cf1701d288,
7361 fidl::encoding::DynamicFlags::empty(),
7362 )
7363 }
7364
7365 type GetNodeRefResponseFut =
7366 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
7367 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
7368 fn _decode(
7369 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7370 ) -> Result<fidl::Event, fidl::Error> {
7371 let _response = fidl::client::decode_transaction_body::<
7372 NodeGetNodeRefResponse,
7373 fidl::encoding::DefaultFuchsiaResourceDialect,
7374 0x467b7c75c35c3b84,
7375 >(_buf?)?;
7376 Ok(_response.node_ref)
7377 }
7378 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
7379 (),
7380 0x467b7c75c35c3b84,
7381 fidl::encoding::DynamicFlags::empty(),
7382 _decode,
7383 )
7384 }
7385
7386 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
7387 NodeIsAlternateForResult,
7388 fidl::encoding::DefaultFuchsiaResourceDialect,
7389 >;
7390 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
7391 fn _decode(
7392 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7393 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
7394 let _response = fidl::client::decode_transaction_body::<
7395 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
7396 fidl::encoding::DefaultFuchsiaResourceDialect,
7397 0x33a2a7aff2776c07,
7398 >(_buf?)?;
7399 Ok(_response.map(|x| x.is_alternate))
7400 }
7401 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
7402 (node_ref,),
7403 0x33a2a7aff2776c07,
7404 fidl::encoding::DynamicFlags::empty(),
7405 _decode,
7406 )
7407 }
7408
7409 fn r#create_child(
7410 &self,
7411 mut payload: BufferCollectionTokenGroupCreateChildRequest,
7412 ) -> Result<(), fidl::Error> {
7413 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
7414 &mut payload,
7415 0x2e74f8bcbf59ee59,
7416 fidl::encoding::DynamicFlags::empty(),
7417 )
7418 }
7419
7420 type CreateChildrenSyncResponseFut = fidl::client::QueryResponseFut<
7421 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7422 fidl::encoding::DefaultFuchsiaResourceDialect,
7423 >;
7424 fn r#create_children_sync(
7425 &self,
7426 mut rights_attenuation_masks: &[fidl::Rights],
7427 ) -> Self::CreateChildrenSyncResponseFut {
7428 fn _decode(
7429 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7430 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error>
7431 {
7432 let _response = fidl::client::decode_transaction_body::<
7433 BufferCollectionTokenGroupCreateChildrenSyncResponse,
7434 fidl::encoding::DefaultFuchsiaResourceDialect,
7435 0x569dc3ca2a98f535,
7436 >(_buf?)?;
7437 Ok(_response.tokens)
7438 }
7439 self.client.send_query_and_decode::<
7440 BufferCollectionTokenGroupCreateChildrenSyncRequest,
7441 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7442 >(
7443 (rights_attenuation_masks,),
7444 0x569dc3ca2a98f535,
7445 fidl::encoding::DynamicFlags::empty(),
7446 _decode,
7447 )
7448 }
7449
7450 fn r#all_children_present(&self) -> Result<(), fidl::Error> {
7451 self.client.send::<fidl::encoding::EmptyPayload>(
7452 (),
7453 0x1d41715f6f044b50,
7454 fidl::encoding::DynamicFlags::empty(),
7455 )
7456 }
7457}
7458
7459pub struct BufferCollectionTokenGroupEventStream {
7460 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
7461}
7462
7463impl std::marker::Unpin for BufferCollectionTokenGroupEventStream {}
7464
7465impl futures::stream::FusedStream for BufferCollectionTokenGroupEventStream {
7466 fn is_terminated(&self) -> bool {
7467 self.event_receiver.is_terminated()
7468 }
7469}
7470
7471impl futures::Stream for BufferCollectionTokenGroupEventStream {
7472 type Item = Result<BufferCollectionTokenGroupEvent, fidl::Error>;
7473
7474 fn poll_next(
7475 mut self: std::pin::Pin<&mut Self>,
7476 cx: &mut std::task::Context<'_>,
7477 ) -> std::task::Poll<Option<Self::Item>> {
7478 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
7479 &mut self.event_receiver,
7480 cx
7481 )?) {
7482 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenGroupEvent::decode(buf))),
7483 None => std::task::Poll::Ready(None),
7484 }
7485 }
7486}
7487
7488#[derive(Debug)]
7489pub enum BufferCollectionTokenGroupEvent {}
7490
7491impl BufferCollectionTokenGroupEvent {
7492 /// Decodes a message buffer as a [`BufferCollectionTokenGroupEvent`].
7493 fn decode(
7494 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
7495 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
7496 let (bytes, _handles) = buf.split_mut();
7497 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7498 debug_assert_eq!(tx_header.tx_id, 0);
7499 match tx_header.ordinal {
7500 _ => Err(fidl::Error::UnknownOrdinal {
7501 ordinal: tx_header.ordinal,
7502 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
7503 })
7504 }
7505 }
7506}
7507
7508/// A Stream of incoming requests for fuchsia.sysmem/BufferCollectionTokenGroup.
7509pub struct BufferCollectionTokenGroupRequestStream {
7510 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7511 is_terminated: bool,
7512}
7513
7514impl std::marker::Unpin for BufferCollectionTokenGroupRequestStream {}
7515
7516impl futures::stream::FusedStream for BufferCollectionTokenGroupRequestStream {
7517 fn is_terminated(&self) -> bool {
7518 self.is_terminated
7519 }
7520}
7521
7522impl fidl::endpoints::RequestStream for BufferCollectionTokenGroupRequestStream {
7523 type Protocol = BufferCollectionTokenGroupMarker;
7524 type ControlHandle = BufferCollectionTokenGroupControlHandle;
7525
7526 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
7527 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
7528 }
7529
7530 fn control_handle(&self) -> Self::ControlHandle {
7531 BufferCollectionTokenGroupControlHandle { inner: self.inner.clone() }
7532 }
7533
7534 fn into_inner(
7535 self,
7536 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
7537 {
7538 (self.inner, self.is_terminated)
7539 }
7540
7541 fn from_inner(
7542 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7543 is_terminated: bool,
7544 ) -> Self {
7545 Self { inner, is_terminated }
7546 }
7547}
7548
7549impl futures::Stream for BufferCollectionTokenGroupRequestStream {
7550 type Item = Result<BufferCollectionTokenGroupRequest, fidl::Error>;
7551
7552 fn poll_next(
7553 mut self: std::pin::Pin<&mut Self>,
7554 cx: &mut std::task::Context<'_>,
7555 ) -> std::task::Poll<Option<Self::Item>> {
7556 let this = &mut *self;
7557 if this.inner.check_shutdown(cx) {
7558 this.is_terminated = true;
7559 return std::task::Poll::Ready(None);
7560 }
7561 if this.is_terminated {
7562 panic!("polled BufferCollectionTokenGroupRequestStream after completion");
7563 }
7564 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
7565 |bytes, handles| {
7566 match this.inner.channel().read_etc(cx, bytes, handles) {
7567 std::task::Poll::Ready(Ok(())) => {}
7568 std::task::Poll::Pending => return std::task::Poll::Pending,
7569 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
7570 this.is_terminated = true;
7571 return std::task::Poll::Ready(None);
7572 }
7573 std::task::Poll::Ready(Err(e)) => {
7574 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
7575 e.into(),
7576 ))));
7577 }
7578 }
7579
7580 // A message has been received from the channel
7581 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7582
7583 std::task::Poll::Ready(Some(match header.ordinal {
7584 0x4577e238ae26291 => {
7585 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7586 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7587 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7588 let control_handle = BufferCollectionTokenGroupControlHandle {
7589 inner: this.inner.clone(),
7590 };
7591 Ok(BufferCollectionTokenGroupRequest::Sync {
7592 responder: BufferCollectionTokenGroupSyncResponder {
7593 control_handle: std::mem::ManuallyDrop::new(control_handle),
7594 tx_id: header.tx_id,
7595 },
7596 })
7597 }
7598 0x5b1d7a4f5681fca7 => {
7599 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7600 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7601 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7602 let control_handle = BufferCollectionTokenGroupControlHandle {
7603 inner: this.inner.clone(),
7604 };
7605 Ok(BufferCollectionTokenGroupRequest::Close {
7606 control_handle,
7607 })
7608 }
7609 0x77a41bb6217e2443 => {
7610 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7611 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7612 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
7613 let control_handle = BufferCollectionTokenGroupControlHandle {
7614 inner: this.inner.clone(),
7615 };
7616 Ok(BufferCollectionTokenGroupRequest::SetName {priority: req.priority,
7617name: req.name,
7618
7619 control_handle,
7620 })
7621 }
7622 0x7275759070eb5ee2 => {
7623 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7624 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7625 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
7626 let control_handle = BufferCollectionTokenGroupControlHandle {
7627 inner: this.inner.clone(),
7628 };
7629 Ok(BufferCollectionTokenGroupRequest::SetDebugClientInfo {name: req.name,
7630id: req.id,
7631
7632 control_handle,
7633 })
7634 }
7635 0x46d38f4772638867 => {
7636 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7637 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7638 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
7639 let control_handle = BufferCollectionTokenGroupControlHandle {
7640 inner: this.inner.clone(),
7641 };
7642 Ok(BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {deadline: req.deadline,
7643
7644 control_handle,
7645 })
7646 }
7647 0x6bfbe2cf1701d288 => {
7648 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7649 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7650 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7651 let control_handle = BufferCollectionTokenGroupControlHandle {
7652 inner: this.inner.clone(),
7653 };
7654 Ok(BufferCollectionTokenGroupRequest::SetVerboseLogging {
7655 control_handle,
7656 })
7657 }
7658 0x467b7c75c35c3b84 => {
7659 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7660 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7661 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7662 let control_handle = BufferCollectionTokenGroupControlHandle {
7663 inner: this.inner.clone(),
7664 };
7665 Ok(BufferCollectionTokenGroupRequest::GetNodeRef {
7666 responder: BufferCollectionTokenGroupGetNodeRefResponder {
7667 control_handle: std::mem::ManuallyDrop::new(control_handle),
7668 tx_id: header.tx_id,
7669 },
7670 })
7671 }
7672 0x33a2a7aff2776c07 => {
7673 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7674 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7675 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
7676 let control_handle = BufferCollectionTokenGroupControlHandle {
7677 inner: this.inner.clone(),
7678 };
7679 Ok(BufferCollectionTokenGroupRequest::IsAlternateFor {node_ref: req.node_ref,
7680
7681 responder: BufferCollectionTokenGroupIsAlternateForResponder {
7682 control_handle: std::mem::ManuallyDrop::new(control_handle),
7683 tx_id: header.tx_id,
7684 },
7685 })
7686 }
7687 0x2e74f8bcbf59ee59 => {
7688 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7689 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7690 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildRequest>(&header, _body_bytes, handles, &mut req)?;
7691 let control_handle = BufferCollectionTokenGroupControlHandle {
7692 inner: this.inner.clone(),
7693 };
7694 Ok(BufferCollectionTokenGroupRequest::CreateChild {payload: req,
7695 control_handle,
7696 })
7697 }
7698 0x569dc3ca2a98f535 => {
7699 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7700 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildrenSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7701 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildrenSyncRequest>(&header, _body_bytes, handles, &mut req)?;
7702 let control_handle = BufferCollectionTokenGroupControlHandle {
7703 inner: this.inner.clone(),
7704 };
7705 Ok(BufferCollectionTokenGroupRequest::CreateChildrenSync {rights_attenuation_masks: req.rights_attenuation_masks,
7706
7707 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder {
7708 control_handle: std::mem::ManuallyDrop::new(control_handle),
7709 tx_id: header.tx_id,
7710 },
7711 })
7712 }
7713 0x1d41715f6f044b50 => {
7714 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7715 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7716 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7717 let control_handle = BufferCollectionTokenGroupControlHandle {
7718 inner: this.inner.clone(),
7719 };
7720 Ok(BufferCollectionTokenGroupRequest::AllChildrenPresent {
7721 control_handle,
7722 })
7723 }
7724 _ => Err(fidl::Error::UnknownOrdinal {
7725 ordinal: header.ordinal,
7726 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
7727 }),
7728 }))
7729 },
7730 )
7731 }
7732}
7733
7734/// The sysmem implementation is guaranteed to be consistent with a logical /
7735/// conceptual model as follows:
7736///
7737/// As usual, a logical allocation considers either the root and all nodes with
7738/// connectivity to the root that don't transit an AttachToken(), or a sub-tree
7739/// rooted at an AttachToken() token and all nodes with connectivity to that
7740/// subtree that don't transit another AttachToken(). This is called the
7741/// logical allocation pruned sub-tree, or pruned sub-tree for short.
7742///
7743/// During constraints aggregation, each BufferCollectionTokenGroup will select
7744/// a single child token among its children. The rest of the children will
7745/// appear to fail the logical allocation, while the selected child may succeed.
7746///
7747/// When more than one BufferCollectionTokenGroup exists in the overall logical
7748/// allocation pruned sub-tree, the relative priority between two groups is
7749/// equivalent to their ordering in a DFS pre-order iteration of the tree, with
7750/// parents higher priority than children, and left children higher priority
7751/// than right children.
7752///
7753/// When a particular child of a group is selected (whether provisionally during
7754/// a constraints aggregation attempt, or as a final selection), the
7755/// non-selection of other children of the group can potentially "hide" other
7756/// groups under those non-selected children.
7757///
7758/// Within a logical allocation, aggregation is attempted first by provisionally
7759/// selecting the child 0 of the highest-priority group, and child 0 of the next
7760/// highest-priority group that isn't hidden by the provisional selections so
7761/// far, etc.
7762///
7763/// If that aggregation attempt fails, aggregation will be attempted with the
7764/// ordinal 0 child of all the same groups except the lowest priority non-hidden
7765/// group which will provisionally select its ordinal 1 child (and then child 2
7766/// and so on). If a new lowest-priority group is un-hidden as provisional
7767/// selections are updated, that newly un-hidden lowest-priority group has all
7768/// its children considered in order, before changing the provisional selection
7769/// in the former lowest-priority group. In terms of result, this is equivalent
7770/// to systematic enumeration of all possible combinations of choices in a
7771/// counting-like order updating the lowest-priority group the most often and
7772/// the highest-priority group the least often. Rather than actually attempting
7773/// aggregation with all the combinations, we can skip over combinations which
7774/// are redundant/equivalent due to hiding without any change to the result.
7775///
7776/// Attempted aggregations of enumerated non-equivalent combinations of choices
7777/// continue in this manner until either (a) all aggregation attempts fail in
7778/// which case the overall logical allocation fails, or (b) until an attempted
7779/// aggregation succeeds, in which case buffer allocation (if needed) is
7780/// attempted once. If buffer allocation based on the first successful
7781/// aggregation fails, the overall logical allocation fails (there is no buffer
7782/// allocation retry / re-attempt). If buffer allocation succeeds (or is not
7783/// needed), the logical allocation succeeds.
7784///
7785/// If this prioritization scheme cannot reasonably work for your usage of
7786/// sysmem, please contact sysmem folks to discuss potentially adding a way to
7787/// achieve what you need.
7788///
7789/// Please avoid creating a large number of BufferCollectionTokenGroup(s) per
7790/// logical allocation, especially with large number of children overall, and
7791/// especially in cases where aggregation may reasonably be expected to often
7792/// fail using ordinal 0 children and possibly with later children as well. We
7793/// anticipate mitigating potentially high time complexity of evaluating too
7794/// many child combinations/selections across too many groups by simply failing
7795/// logical allocation beyond a certain (fairly high, but not huge) max number
7796/// of considered group child combinations/selections. More advanced (and more
7797/// complicated) mitigation is not anticipated to be practically necessary or
7798/// worth the added complexity. Please contact sysmem folks if the max limit
7799/// is getting hit or if you anticipate it getting hit, to discuss potential
7800/// options.
7801///
7802/// Prefer to use multiple ImageFormatConstraints in a single
7803/// BufferCollectionConstraints when feasible (when a participant just needs to
7804/// express the ability to work with more than a single PixelFormat, with
7805/// sysmem choosing which PixelFormat to use among those supported by all
7806/// participants).
7807///
7808/// Similar to BufferCollectionToken and BufferCollection, closure of the
7809/// BufferCollectionTokenGroup channel without sending Close() first will cause
7810/// logical buffer collection failure (or sub-tree failure if using
7811/// SetDispensable() or AttachToken() and the BufferCollectionTokenGroup is part
7812/// of a sub-tree under such a node that doesn't propagate failure to its
7813/// parent).
7814#[derive(Debug)]
7815pub enum BufferCollectionTokenGroupRequest {
7816 /// Ensure that previous messages, including Duplicate() messages on a
7817 /// token, collection, or group, have been received server side.
7818 ///
7819 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
7820 /// valid sysmem token risks the Sync() hanging forever. See
7821 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
7822 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
7823 /// Another way is to pass the token to BindSharedCollection(), which also
7824 /// validates the token as part of exchanging it for a BufferCollection
7825 /// channel, and BufferCollection Sync() can then be used.
7826 ///
7827 /// After a Sync(), it's then safe to send the client end of token_request
7828 /// to another participant knowing the server will recognize the token when
7829 /// it's sent into BindSharedCollection() by the other participant.
7830 ///
7831 /// Other options include waiting for each token.Duplicate() to complete
7832 /// individually (using separate call to token.Sync() after each), or
7833 /// calling Sync() on BufferCollection after the token has been turned in
7834 /// via BindSharedCollection().
7835 ///
7836 /// Another way to mitigate is to avoid calling Sync() on the token, and
7837 /// instead later deal with potential failure of BufferCollection.Sync() if
7838 /// the original token was invalid. This option can be preferable from a
7839 /// performance point of view, but requires client code to delay sending
7840 /// tokens duplicated from this token until after client code has converted
7841 /// the duplicating token to a BufferCollection and received successful
7842 /// response from BufferCollection.Sync().
7843 ///
7844 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
7845 /// When BufferCollection.Sync() isn't feasible, the caller must already
7846 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
7847 /// hang forever. See ValidateBufferCollectionToken() to check token
7848 /// validity first if the token isn't already known to be (is/was) valid.
7849 Sync { responder: BufferCollectionTokenGroupSyncResponder },
7850 /// On a BufferCollectionToken channel:
7851 ///
7852 /// Normally a participant will convert a BufferCollectionToken into a
7853 /// BufferCollection view, but a participant is also free to Close() the
7854 /// token (and then close the channel immediately or shortly later in
7855 /// response to server closing its end), which avoids causing logical buffer
7856 /// collection failure. Â Normally an unexpected token channel close will
7857 /// cause logical buffer collection failure (the only exceptions being
7858 /// certain cases involving AttachToken() or SetDispensable()).
7859 ///
7860 /// On a BufferCollection channel:
7861 ///
7862 /// By default the server handles unexpected failure of a BufferCollection
7863 /// by failing the whole logical buffer collection. Partly this is to
7864 /// expedite closing VMO handles to reclaim memory when any participant
7865 /// fails. If a participant would like to cleanly close a BufferCollection
7866 /// view without causing logical buffer collection failure, the participant
7867 /// can send Close() before closing the client end of the BufferCollection
7868 /// channel. If this is the last BufferCollection view, the logical buffer
7869 /// collection will still go away. The Close() can occur before or after
7870 /// SetConstraints(). If before SetConstraints(), the buffer collection
7871 /// won't require constraints from this node in order to allocate. If
7872 /// after SetConstraints(), the constraints are retained and aggregated
7873 /// along with any subsequent logical allocation(s), despite the lack of
7874 /// channel connection.
7875 ///
7876 /// On a BufferCollectionTokenGroup channel:
7877 ///
7878 /// By default, unexpected failure of a BufferCollectionTokenGroup will
7879 /// trigger failure of the logical BufferCollectionTokenGroup and will
7880 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
7881 /// channel without failing the logical group or propagating failure, send
7882 /// Close() before closing the channel client endpoint.
7883 ///
7884 /// If Close() occurs before AllChildrenPresent(), the logical buffer
7885 /// collection will still fail despite the Close() (because sysmem can't be
7886 /// sure whether all relevant children were created, so it's ambiguous
7887 /// whether all relevant constraints will be provided to sysmem). If
7888 /// Close() occurs after AllChildrenPresent(), the children and all their
7889 /// constraints remain intact (just as they would if the
7890 /// BufferCollectionTokenGroup channel had remained open), and the close
7891 /// doesn't trigger or propagate failure.
7892 Close { control_handle: BufferCollectionTokenGroupControlHandle },
7893 /// Set a name for VMOs in this buffer collection. The name may be truncated
7894 /// shorter. The name only affects VMOs allocated after it's set - this call
7895 /// does not rename existing VMOs. If multiple clients set different names
7896 /// then the larger priority value will win.
7897 SetName { priority: u32, name: String, control_handle: BufferCollectionTokenGroupControlHandle },
7898 /// Set information about the current client that can be used by sysmem to
7899 /// help debug leaking memory and hangs waiting for constraints. |name| can
7900 /// be an arbitrary string, but the current process name (see
7901 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
7902 /// arbitrary id, but the current process ID (see
7903 /// fsl::GetCurrentProcessKoid()) is a good default.
7904 ///
7905 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
7906 /// indicate which client is closing their channel first, leading to
7907 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
7908 /// over, but if happening earlier than expected, the
7909 /// client-channel-specific name can help diagnose where the failure is
7910 /// first coming from, from sysmem's point of view).
7911 ///
7912 /// By default (unless overriden by this message or using
7913 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
7914 /// parent Node at the time the child Node is created. While this can be
7915 /// better than nothing, it's often better for each participant to use
7916 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
7917 /// info directly relevant to the current client. Also, SetVerboseLogging()
7918 /// can be used to help disambiguate if a Node is suspected of having info
7919 /// that was copied from its parent.
7920 SetDebugClientInfo {
7921 name: String,
7922 id: u64,
7923 control_handle: BufferCollectionTokenGroupControlHandle,
7924 },
7925 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
7926 /// after creating a collection. Clients can call this method to change
7927 /// when the log is printed. If multiple client set the deadline, it's
7928 /// unspecified which deadline will take effect.
7929 SetDebugTimeoutLogDeadline {
7930 deadline: i64,
7931 control_handle: BufferCollectionTokenGroupControlHandle,
7932 },
7933 /// Verbose logging includes constraints set via SetConstraints() from each
7934 /// client along with info set via SetDebugClientInfo() and the structure of
7935 /// the tree of Node(s).
7936 ///
7937 /// Normally sysmem prints only a single line complaint when aggregation
7938 /// fails, with just the specific detailed reason that aggregation failed,
7939 /// with minimal context. While this is often enough to diagnose a problem
7940 /// if only a small change was made and the system had been working before
7941 /// the small change, it's often not particularly helpful for getting a new
7942 /// buffer collection to work for the first time. Especially with more
7943 /// complex trees of nodes, involving things like AttachToken(),
7944 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
7945 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
7946 /// looks like and why it's failing a logical allocation, or why a tree or
7947 /// sub-tree is failing sooner than expected.
7948 ///
7949 /// The intent of the extra logging is to be acceptable from a performance
7950 /// point of view, if only enabled on a low number of buffer collections.
7951 /// If we're not tracking down a bug, we shouldn't send this message.
7952 ///
7953 /// If too many participants leave verbose logging enabled, we may end up
7954 /// needing to require that system-wide sysmem verbose logging be permitted
7955 /// via some other setting, to avoid sysmem spamming the log too much due to
7956 /// this message.
7957 ///
7958 /// This may be a NOP for some nodes due to intentional policy associated
7959 /// with the node, if we don't trust a node enough to let it turn on verbose
7960 /// logging.
7961 SetVerboseLogging { control_handle: BufferCollectionTokenGroupControlHandle },
7962 /// This gets an event handle that can be used as a parameter to
7963 /// IsAlternateFor() called on any Node. The client will not be granted the
7964 /// right to signal this event, as this handle should only be used as proof
7965 /// that the client obtained this handle from this Node.
7966 ///
7967 /// Because this is a get not a set, no Sync() is needed between the
7968 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
7969 /// potentially being on different channels.
7970 ///
7971 /// See also IsAlternateFor().
7972 GetNodeRef { responder: BufferCollectionTokenGroupGetNodeRefResponder },
7973 /// This checks whether the calling node is in a subtree rooted at a
7974 /// different child token of a common parent BufferCollectionTokenGroup, in
7975 /// relation to the passed-in node_ref.
7976 ///
7977 /// This call is for assisting with admission control de-duplication, and
7978 /// with debugging.
7979 ///
7980 /// The node_ref must be obtained using GetNodeRef() of a
7981 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
7982 ///
7983 /// The node_ref can be a duplicated handle; it's not necessary to call
7984 /// GetNodeRef() for every call to IsAlternateFor().
7985 ///
7986 /// If a calling token may not actually be a valid token at all due to
7987 /// a potentially hostile/untrusted provider of the token, call
7988 /// ValidateBufferCollectionToken() first instead of potentially getting
7989 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
7990 /// token not being a real token (not really talking to sysmem). Another
7991 /// option is to call BindSharedCollection with this token first which also
7992 /// validates the token along with converting it to a BufferCollection, then
7993 /// call BufferCollection IsAlternateFor().
7994 ///
7995 /// error values:
7996 ///
7997 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
7998 /// buffer collection as the calling Node. Before logical allocation and
7999 /// within the same logical allocation sub-tree, this essentially means that
8000 /// the node_ref was never part of this logical buffer collection, since
8001 /// before logical allocation all node_refs that come into existence remain
8002 /// in existence at least until logical allocation (including Node(s) that
8003 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
8004 /// to be returned, this Node's channel needs to still be connected server
8005 /// side, which won't be the case if the whole logical allocation has
8006 /// failed. After logical allocation or in a different logical allocation
8007 /// sub-tree there are additional potential reasons for this error. For
8008 /// example a different logical allocation (separated from this Node(s)
8009 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
8010 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
8011 /// exist and may select a different child sub-tree than the sub-tree the
8012 /// node_ref is in causing deletion of the node_ref Node. The only time
8013 /// sysmem keeps a Node around after that Node has no corresponding channel
8014 /// is when Close() is used and the Node's sub-tree has not yet failed.
8015 /// Another reason for this error is if the node_ref is an eventpair handle
8016 /// with sufficient rights, but isn't actually a real node_ref obtained from
8017 /// GetNodeRef().
8018 ///
8019 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
8020 /// eventpair handle, or doesn't have the needed rights expected on a real
8021 /// node_ref.
8022 ///
8023 /// No other failing status codes are returned by this call. However,
8024 /// sysmem may add additional codes in future, so the client should have
8025 /// sensible default handling for any failing status code.
8026 ///
8027 /// On success, is_alternate has the following meaning:
8028 /// * true - The first parent node in common between the calling node and
8029 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
8030 /// the calling Node and the node_ref Node will _not_ have both their
8031 /// constraints apply - rather sysmem will choose one or the other of
8032 /// the constraints - never both. This is because only one child of
8033 /// a BufferCollectionTokenGroup is selected during logical allocation,
8034 /// with only that one child's sub-tree contributing to constraints
8035 /// aggregation.
8036 /// * false - The first parent node in common between the calling Node and
8037 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
8038 /// this means the first parent node in common is a
8039 /// BufferCollectionToken or BufferCollection (regardless of not
8040 /// Close()ed or Close()ed). This means that the calling Node and the
8041 /// node_ref Node _may_ have both their constraints apply during
8042 /// constraints aggregation of the logical allocation, if both Node(s)
8043 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
8044 /// In this case, there is no BufferCollectionTokenGroup that will
8045 /// directly prevent the two Node(s) from both being selected and their
8046 /// constraints both aggregated, but even when false, one or both
8047 /// Node(s) may still be eliminated from consideration if one or both
8048 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
8049 /// which selects a child sub-tree other than the sub-tree containing
8050 /// the calling Node or node_ref Node.
8051 IsAlternateFor {
8052 node_ref: fidl::Event,
8053 responder: BufferCollectionTokenGroupIsAlternateForResponder,
8054 },
8055 /// Create a child token. Before passing the client end of this token to
8056 /// BindSharedCollection(), completion of Sync() after CreateChild() is
8057 /// required. Or the client can use CreateChildrenSync() which essentially
8058 /// includes the Sync().
8059 ///
8060 /// token_request - the server end of the new token channel.
8061 ///
8062 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
8063 /// allows the holder to get the same rights to buffers as the parent token
8064 /// (of the group) had.
8065 CreateChild {
8066 payload: BufferCollectionTokenGroupCreateChildRequest,
8067 control_handle: BufferCollectionTokenGroupControlHandle,
8068 },
8069 /// Create 1 or more child tokens at once, synchronously. In contrast to
8070 /// CreateChild(), no Sync() completion is required before passing the
8071 /// client end of a returned token to BindSharedCollection().
8072 ///
8073 /// The size of the rights_attentuation_mask determines the number of
8074 /// created child tokens.
8075 ///
8076 /// The lower-index child tokens are higher priority (attempted sooner) than
8077 /// higher-index child tokens.
8078 ///
8079 /// As per all child tokens, successful aggregation will choose exactly one
8080 /// child among all created children (across all children created across
8081 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
8082 ///
8083 /// The maximum permissible total number of children per group, and total
8084 /// number of nodes in an overall tree (from the root) are capped to limits
8085 /// which are not configurable via these protocols.
8086 CreateChildrenSync {
8087 rights_attenuation_masks: Vec<fidl::Rights>,
8088 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder,
8089 },
8090 /// AllChildrenPresent()
8091 ///
8092 /// After creating all children, the client must call AllChildrenPresent()
8093 /// to inform sysmem that no more children will be created, so that sysmem
8094 /// can know when it's ok to start aggregating constraints.
8095 ///
8096 /// If Close() is to be sent, it should be sent _after_
8097 /// AllChildrenPresent(), else failure of the group and propagation of the
8098 /// failure to the group's parent will still be triggered.
8099 AllChildrenPresent { control_handle: BufferCollectionTokenGroupControlHandle },
8100}
8101
8102impl BufferCollectionTokenGroupRequest {
8103 #[allow(irrefutable_let_patterns)]
8104 pub fn into_sync(self) -> Option<(BufferCollectionTokenGroupSyncResponder)> {
8105 if let BufferCollectionTokenGroupRequest::Sync { responder } = self {
8106 Some((responder))
8107 } else {
8108 None
8109 }
8110 }
8111
8112 #[allow(irrefutable_let_patterns)]
8113 pub fn into_close(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8114 if let BufferCollectionTokenGroupRequest::Close { control_handle } = self {
8115 Some((control_handle))
8116 } else {
8117 None
8118 }
8119 }
8120
8121 #[allow(irrefutable_let_patterns)]
8122 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionTokenGroupControlHandle)> {
8123 if let BufferCollectionTokenGroupRequest::SetName { priority, name, control_handle } = self
8124 {
8125 Some((priority, name, control_handle))
8126 } else {
8127 None
8128 }
8129 }
8130
8131 #[allow(irrefutable_let_patterns)]
8132 pub fn into_set_debug_client_info(
8133 self,
8134 ) -> Option<(String, u64, BufferCollectionTokenGroupControlHandle)> {
8135 if let BufferCollectionTokenGroupRequest::SetDebugClientInfo { name, id, control_handle } =
8136 self
8137 {
8138 Some((name, id, control_handle))
8139 } else {
8140 None
8141 }
8142 }
8143
8144 #[allow(irrefutable_let_patterns)]
8145 pub fn into_set_debug_timeout_log_deadline(
8146 self,
8147 ) -> Option<(i64, BufferCollectionTokenGroupControlHandle)> {
8148 if let BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {
8149 deadline,
8150 control_handle,
8151 } = self
8152 {
8153 Some((deadline, control_handle))
8154 } else {
8155 None
8156 }
8157 }
8158
8159 #[allow(irrefutable_let_patterns)]
8160 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8161 if let BufferCollectionTokenGroupRequest::SetVerboseLogging { control_handle } = self {
8162 Some((control_handle))
8163 } else {
8164 None
8165 }
8166 }
8167
8168 #[allow(irrefutable_let_patterns)]
8169 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGroupGetNodeRefResponder)> {
8170 if let BufferCollectionTokenGroupRequest::GetNodeRef { responder } = self {
8171 Some((responder))
8172 } else {
8173 None
8174 }
8175 }
8176
8177 #[allow(irrefutable_let_patterns)]
8178 pub fn into_is_alternate_for(
8179 self,
8180 ) -> Option<(fidl::Event, BufferCollectionTokenGroupIsAlternateForResponder)> {
8181 if let BufferCollectionTokenGroupRequest::IsAlternateFor { node_ref, responder } = self {
8182 Some((node_ref, responder))
8183 } else {
8184 None
8185 }
8186 }
8187
8188 #[allow(irrefutable_let_patterns)]
8189 pub fn into_create_child(
8190 self,
8191 ) -> Option<(
8192 BufferCollectionTokenGroupCreateChildRequest,
8193 BufferCollectionTokenGroupControlHandle,
8194 )> {
8195 if let BufferCollectionTokenGroupRequest::CreateChild { payload, control_handle } = self {
8196 Some((payload, control_handle))
8197 } else {
8198 None
8199 }
8200 }
8201
8202 #[allow(irrefutable_let_patterns)]
8203 pub fn into_create_children_sync(
8204 self,
8205 ) -> Option<(Vec<fidl::Rights>, BufferCollectionTokenGroupCreateChildrenSyncResponder)> {
8206 if let BufferCollectionTokenGroupRequest::CreateChildrenSync {
8207 rights_attenuation_masks,
8208 responder,
8209 } = self
8210 {
8211 Some((rights_attenuation_masks, responder))
8212 } else {
8213 None
8214 }
8215 }
8216
8217 #[allow(irrefutable_let_patterns)]
8218 pub fn into_all_children_present(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8219 if let BufferCollectionTokenGroupRequest::AllChildrenPresent { control_handle } = self {
8220 Some((control_handle))
8221 } else {
8222 None
8223 }
8224 }
8225
8226 /// Name of the method defined in FIDL
8227 pub fn method_name(&self) -> &'static str {
8228 match *self {
8229 BufferCollectionTokenGroupRequest::Sync { .. } => "sync",
8230 BufferCollectionTokenGroupRequest::Close { .. } => "close",
8231 BufferCollectionTokenGroupRequest::SetName { .. } => "set_name",
8232 BufferCollectionTokenGroupRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
8233 BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline { .. } => {
8234 "set_debug_timeout_log_deadline"
8235 }
8236 BufferCollectionTokenGroupRequest::SetVerboseLogging { .. } => "set_verbose_logging",
8237 BufferCollectionTokenGroupRequest::GetNodeRef { .. } => "get_node_ref",
8238 BufferCollectionTokenGroupRequest::IsAlternateFor { .. } => "is_alternate_for",
8239 BufferCollectionTokenGroupRequest::CreateChild { .. } => "create_child",
8240 BufferCollectionTokenGroupRequest::CreateChildrenSync { .. } => "create_children_sync",
8241 BufferCollectionTokenGroupRequest::AllChildrenPresent { .. } => "all_children_present",
8242 }
8243 }
8244}
8245
8246#[derive(Debug, Clone)]
8247pub struct BufferCollectionTokenGroupControlHandle {
8248 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
8249}
8250
8251impl fidl::endpoints::ControlHandle for BufferCollectionTokenGroupControlHandle {
8252 fn shutdown(&self) {
8253 self.inner.shutdown()
8254 }
8255 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
8256 self.inner.shutdown_with_epitaph(status)
8257 }
8258
8259 fn is_closed(&self) -> bool {
8260 self.inner.channel().is_closed()
8261 }
8262 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
8263 self.inner.channel().on_closed()
8264 }
8265
8266 #[cfg(target_os = "fuchsia")]
8267 fn signal_peer(
8268 &self,
8269 clear_mask: zx::Signals,
8270 set_mask: zx::Signals,
8271 ) -> Result<(), zx_status::Status> {
8272 use fidl::Peered;
8273 self.inner.channel().signal_peer(clear_mask, set_mask)
8274 }
8275}
8276
8277impl BufferCollectionTokenGroupControlHandle {}
8278
8279#[must_use = "FIDL methods require a response to be sent"]
8280#[derive(Debug)]
8281pub struct BufferCollectionTokenGroupSyncResponder {
8282 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8283 tx_id: u32,
8284}
8285
8286/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8287/// if the responder is dropped without sending a response, so that the client
8288/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8289impl std::ops::Drop for BufferCollectionTokenGroupSyncResponder {
8290 fn drop(&mut self) {
8291 self.control_handle.shutdown();
8292 // Safety: drops once, never accessed again
8293 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8294 }
8295}
8296
8297impl fidl::endpoints::Responder for BufferCollectionTokenGroupSyncResponder {
8298 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8299
8300 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8301 &self.control_handle
8302 }
8303
8304 fn drop_without_shutdown(mut self) {
8305 // Safety: drops once, never accessed again due to mem::forget
8306 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8307 // Prevent Drop from running (which would shut down the channel)
8308 std::mem::forget(self);
8309 }
8310}
8311
8312impl BufferCollectionTokenGroupSyncResponder {
8313 /// Sends a response to the FIDL transaction.
8314 ///
8315 /// Sets the channel to shutdown if an error occurs.
8316 pub fn send(self) -> Result<(), fidl::Error> {
8317 let _result = self.send_raw();
8318 if _result.is_err() {
8319 self.control_handle.shutdown();
8320 }
8321 self.drop_without_shutdown();
8322 _result
8323 }
8324
8325 /// Similar to "send" but does not shutdown the channel if an error occurs.
8326 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
8327 let _result = self.send_raw();
8328 self.drop_without_shutdown();
8329 _result
8330 }
8331
8332 fn send_raw(&self) -> Result<(), fidl::Error> {
8333 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
8334 (),
8335 self.tx_id,
8336 0x4577e238ae26291,
8337 fidl::encoding::DynamicFlags::empty(),
8338 )
8339 }
8340}
8341
8342#[must_use = "FIDL methods require a response to be sent"]
8343#[derive(Debug)]
8344pub struct BufferCollectionTokenGroupGetNodeRefResponder {
8345 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8346 tx_id: u32,
8347}
8348
8349/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8350/// if the responder is dropped without sending a response, so that the client
8351/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8352impl std::ops::Drop for BufferCollectionTokenGroupGetNodeRefResponder {
8353 fn drop(&mut self) {
8354 self.control_handle.shutdown();
8355 // Safety: drops once, never accessed again
8356 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8357 }
8358}
8359
8360impl fidl::endpoints::Responder for BufferCollectionTokenGroupGetNodeRefResponder {
8361 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8362
8363 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8364 &self.control_handle
8365 }
8366
8367 fn drop_without_shutdown(mut self) {
8368 // Safety: drops once, never accessed again due to mem::forget
8369 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8370 // Prevent Drop from running (which would shut down the channel)
8371 std::mem::forget(self);
8372 }
8373}
8374
8375impl BufferCollectionTokenGroupGetNodeRefResponder {
8376 /// Sends a response to the FIDL transaction.
8377 ///
8378 /// Sets the channel to shutdown if an error occurs.
8379 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8380 let _result = self.send_raw(node_ref);
8381 if _result.is_err() {
8382 self.control_handle.shutdown();
8383 }
8384 self.drop_without_shutdown();
8385 _result
8386 }
8387
8388 /// Similar to "send" but does not shutdown the channel if an error occurs.
8389 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8390 let _result = self.send_raw(node_ref);
8391 self.drop_without_shutdown();
8392 _result
8393 }
8394
8395 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8396 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
8397 (node_ref,),
8398 self.tx_id,
8399 0x467b7c75c35c3b84,
8400 fidl::encoding::DynamicFlags::empty(),
8401 )
8402 }
8403}
8404
8405#[must_use = "FIDL methods require a response to be sent"]
8406#[derive(Debug)]
8407pub struct BufferCollectionTokenGroupIsAlternateForResponder {
8408 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8409 tx_id: u32,
8410}
8411
8412/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8413/// if the responder is dropped without sending a response, so that the client
8414/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8415impl std::ops::Drop for BufferCollectionTokenGroupIsAlternateForResponder {
8416 fn drop(&mut self) {
8417 self.control_handle.shutdown();
8418 // Safety: drops once, never accessed again
8419 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8420 }
8421}
8422
8423impl fidl::endpoints::Responder for BufferCollectionTokenGroupIsAlternateForResponder {
8424 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8425
8426 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8427 &self.control_handle
8428 }
8429
8430 fn drop_without_shutdown(mut self) {
8431 // Safety: drops once, never accessed again due to mem::forget
8432 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8433 // Prevent Drop from running (which would shut down the channel)
8434 std::mem::forget(self);
8435 }
8436}
8437
8438impl BufferCollectionTokenGroupIsAlternateForResponder {
8439 /// Sends a response to the FIDL transaction.
8440 ///
8441 /// Sets the channel to shutdown if an error occurs.
8442 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8443 let _result = self.send_raw(result);
8444 if _result.is_err() {
8445 self.control_handle.shutdown();
8446 }
8447 self.drop_without_shutdown();
8448 _result
8449 }
8450
8451 /// Similar to "send" but does not shutdown the channel if an error occurs.
8452 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8453 let _result = self.send_raw(result);
8454 self.drop_without_shutdown();
8455 _result
8456 }
8457
8458 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8459 self.control_handle
8460 .inner
8461 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
8462 result.map(|is_alternate| (is_alternate,)),
8463 self.tx_id,
8464 0x33a2a7aff2776c07,
8465 fidl::encoding::DynamicFlags::empty(),
8466 )
8467 }
8468}
8469
8470#[must_use = "FIDL methods require a response to be sent"]
8471#[derive(Debug)]
8472pub struct BufferCollectionTokenGroupCreateChildrenSyncResponder {
8473 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8474 tx_id: u32,
8475}
8476
8477/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8478/// if the responder is dropped without sending a response, so that the client
8479/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8480impl std::ops::Drop for BufferCollectionTokenGroupCreateChildrenSyncResponder {
8481 fn drop(&mut self) {
8482 self.control_handle.shutdown();
8483 // Safety: drops once, never accessed again
8484 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8485 }
8486}
8487
8488impl fidl::endpoints::Responder for BufferCollectionTokenGroupCreateChildrenSyncResponder {
8489 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8490
8491 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8492 &self.control_handle
8493 }
8494
8495 fn drop_without_shutdown(mut self) {
8496 // Safety: drops once, never accessed again due to mem::forget
8497 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8498 // Prevent Drop from running (which would shut down the channel)
8499 std::mem::forget(self);
8500 }
8501}
8502
8503impl BufferCollectionTokenGroupCreateChildrenSyncResponder {
8504 /// Sends a response to the FIDL transaction.
8505 ///
8506 /// Sets the channel to shutdown if an error occurs.
8507 pub fn send(
8508 self,
8509 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8510 ) -> Result<(), fidl::Error> {
8511 let _result = self.send_raw(tokens);
8512 if _result.is_err() {
8513 self.control_handle.shutdown();
8514 }
8515 self.drop_without_shutdown();
8516 _result
8517 }
8518
8519 /// Similar to "send" but does not shutdown the channel if an error occurs.
8520 pub fn send_no_shutdown_on_err(
8521 self,
8522 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8523 ) -> Result<(), fidl::Error> {
8524 let _result = self.send_raw(tokens);
8525 self.drop_without_shutdown();
8526 _result
8527 }
8528
8529 fn send_raw(
8530 &self,
8531 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8532 ) -> Result<(), fidl::Error> {
8533 self.control_handle.inner.send::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(
8534 (tokens.as_mut(),),
8535 self.tx_id,
8536 0x569dc3ca2a98f535,
8537 fidl::encoding::DynamicFlags::empty(),
8538 )
8539 }
8540}
8541
8542#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
8543pub struct NodeMarker;
8544
8545impl fidl::endpoints::ProtocolMarker for NodeMarker {
8546 type Proxy = NodeProxy;
8547 type RequestStream = NodeRequestStream;
8548 #[cfg(target_os = "fuchsia")]
8549 type SynchronousProxy = NodeSynchronousProxy;
8550
8551 const DEBUG_NAME: &'static str = "(anonymous) Node";
8552}
8553pub type NodeIsAlternateForResult = Result<bool, i32>;
8554
8555pub trait NodeProxyInterface: Send + Sync {
8556 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
8557 fn r#sync(&self) -> Self::SyncResponseFut;
8558 fn r#close(&self) -> Result<(), fidl::Error>;
8559 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
8560 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
8561 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
8562 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
8563 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
8564 + Send;
8565 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
8566 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
8567 + Send;
8568 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
8569}
8570#[derive(Debug)]
8571#[cfg(target_os = "fuchsia")]
8572pub struct NodeSynchronousProxy {
8573 client: fidl::client::sync::Client,
8574}
8575
8576#[cfg(target_os = "fuchsia")]
8577impl fidl::endpoints::SynchronousProxy for NodeSynchronousProxy {
8578 type Proxy = NodeProxy;
8579 type Protocol = NodeMarker;
8580
8581 fn from_channel(inner: fidl::Channel) -> Self {
8582 Self::new(inner)
8583 }
8584
8585 fn into_channel(self) -> fidl::Channel {
8586 self.client.into_channel()
8587 }
8588
8589 fn as_channel(&self) -> &fidl::Channel {
8590 self.client.as_channel()
8591 }
8592}
8593
8594#[cfg(target_os = "fuchsia")]
8595impl NodeSynchronousProxy {
8596 pub fn new(channel: fidl::Channel) -> Self {
8597 let protocol_name = <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
8598 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
8599 }
8600
8601 pub fn into_channel(self) -> fidl::Channel {
8602 self.client.into_channel()
8603 }
8604
8605 /// Waits until an event arrives and returns it. It is safe for other
8606 /// threads to make concurrent requests while waiting for an event.
8607 pub fn wait_for_event(&self, deadline: zx::MonotonicInstant) -> Result<NodeEvent, fidl::Error> {
8608 NodeEvent::decode(self.client.wait_for_event(deadline)?)
8609 }
8610
8611 /// Ensure that previous messages, including Duplicate() messages on a
8612 /// token, collection, or group, have been received server side.
8613 ///
8614 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
8615 /// valid sysmem token risks the Sync() hanging forever. See
8616 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
8617 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
8618 /// Another way is to pass the token to BindSharedCollection(), which also
8619 /// validates the token as part of exchanging it for a BufferCollection
8620 /// channel, and BufferCollection Sync() can then be used.
8621 ///
8622 /// After a Sync(), it's then safe to send the client end of token_request
8623 /// to another participant knowing the server will recognize the token when
8624 /// it's sent into BindSharedCollection() by the other participant.
8625 ///
8626 /// Other options include waiting for each token.Duplicate() to complete
8627 /// individually (using separate call to token.Sync() after each), or
8628 /// calling Sync() on BufferCollection after the token has been turned in
8629 /// via BindSharedCollection().
8630 ///
8631 /// Another way to mitigate is to avoid calling Sync() on the token, and
8632 /// instead later deal with potential failure of BufferCollection.Sync() if
8633 /// the original token was invalid. This option can be preferable from a
8634 /// performance point of view, but requires client code to delay sending
8635 /// tokens duplicated from this token until after client code has converted
8636 /// the duplicating token to a BufferCollection and received successful
8637 /// response from BufferCollection.Sync().
8638 ///
8639 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
8640 /// When BufferCollection.Sync() isn't feasible, the caller must already
8641 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
8642 /// hang forever. See ValidateBufferCollectionToken() to check token
8643 /// validity first if the token isn't already known to be (is/was) valid.
8644 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
8645 let _response =
8646 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
8647 (),
8648 0x4577e238ae26291,
8649 fidl::encoding::DynamicFlags::empty(),
8650 ___deadline,
8651 )?;
8652 Ok(_response)
8653 }
8654
8655 /// On a BufferCollectionToken channel:
8656 ///
8657 /// Normally a participant will convert a BufferCollectionToken into a
8658 /// BufferCollection view, but a participant is also free to Close() the
8659 /// token (and then close the channel immediately or shortly later in
8660 /// response to server closing its end), which avoids causing logical buffer
8661 /// collection failure. Â Normally an unexpected token channel close will
8662 /// cause logical buffer collection failure (the only exceptions being
8663 /// certain cases involving AttachToken() or SetDispensable()).
8664 ///
8665 /// On a BufferCollection channel:
8666 ///
8667 /// By default the server handles unexpected failure of a BufferCollection
8668 /// by failing the whole logical buffer collection. Partly this is to
8669 /// expedite closing VMO handles to reclaim memory when any participant
8670 /// fails. If a participant would like to cleanly close a BufferCollection
8671 /// view without causing logical buffer collection failure, the participant
8672 /// can send Close() before closing the client end of the BufferCollection
8673 /// channel. If this is the last BufferCollection view, the logical buffer
8674 /// collection will still go away. The Close() can occur before or after
8675 /// SetConstraints(). If before SetConstraints(), the buffer collection
8676 /// won't require constraints from this node in order to allocate. If
8677 /// after SetConstraints(), the constraints are retained and aggregated
8678 /// along with any subsequent logical allocation(s), despite the lack of
8679 /// channel connection.
8680 ///
8681 /// On a BufferCollectionTokenGroup channel:
8682 ///
8683 /// By default, unexpected failure of a BufferCollectionTokenGroup will
8684 /// trigger failure of the logical BufferCollectionTokenGroup and will
8685 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
8686 /// channel without failing the logical group or propagating failure, send
8687 /// Close() before closing the channel client endpoint.
8688 ///
8689 /// If Close() occurs before AllChildrenPresent(), the logical buffer
8690 /// collection will still fail despite the Close() (because sysmem can't be
8691 /// sure whether all relevant children were created, so it's ambiguous
8692 /// whether all relevant constraints will be provided to sysmem). If
8693 /// Close() occurs after AllChildrenPresent(), the children and all their
8694 /// constraints remain intact (just as they would if the
8695 /// BufferCollectionTokenGroup channel had remained open), and the close
8696 /// doesn't trigger or propagate failure.
8697 pub fn r#close(&self) -> Result<(), fidl::Error> {
8698 self.client.send::<fidl::encoding::EmptyPayload>(
8699 (),
8700 0x5b1d7a4f5681fca7,
8701 fidl::encoding::DynamicFlags::empty(),
8702 )
8703 }
8704
8705 /// Set a name for VMOs in this buffer collection. The name may be truncated
8706 /// shorter. The name only affects VMOs allocated after it's set - this call
8707 /// does not rename existing VMOs. If multiple clients set different names
8708 /// then the larger priority value will win.
8709 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
8710 self.client.send::<NodeSetNameRequest>(
8711 (priority, name),
8712 0x77a41bb6217e2443,
8713 fidl::encoding::DynamicFlags::empty(),
8714 )
8715 }
8716
8717 /// Set information about the current client that can be used by sysmem to
8718 /// help debug leaking memory and hangs waiting for constraints. |name| can
8719 /// be an arbitrary string, but the current process name (see
8720 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
8721 /// arbitrary id, but the current process ID (see
8722 /// fsl::GetCurrentProcessKoid()) is a good default.
8723 ///
8724 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
8725 /// indicate which client is closing their channel first, leading to
8726 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
8727 /// over, but if happening earlier than expected, the
8728 /// client-channel-specific name can help diagnose where the failure is
8729 /// first coming from, from sysmem's point of view).
8730 ///
8731 /// By default (unless overriden by this message or using
8732 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
8733 /// parent Node at the time the child Node is created. While this can be
8734 /// better than nothing, it's often better for each participant to use
8735 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
8736 /// info directly relevant to the current client. Also, SetVerboseLogging()
8737 /// can be used to help disambiguate if a Node is suspected of having info
8738 /// that was copied from its parent.
8739 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
8740 self.client.send::<NodeSetDebugClientInfoRequest>(
8741 (name, id),
8742 0x7275759070eb5ee2,
8743 fidl::encoding::DynamicFlags::empty(),
8744 )
8745 }
8746
8747 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
8748 /// after creating a collection. Clients can call this method to change
8749 /// when the log is printed. If multiple client set the deadline, it's
8750 /// unspecified which deadline will take effect.
8751 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
8752 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
8753 (deadline,),
8754 0x46d38f4772638867,
8755 fidl::encoding::DynamicFlags::empty(),
8756 )
8757 }
8758
8759 /// Verbose logging includes constraints set via SetConstraints() from each
8760 /// client along with info set via SetDebugClientInfo() and the structure of
8761 /// the tree of Node(s).
8762 ///
8763 /// Normally sysmem prints only a single line complaint when aggregation
8764 /// fails, with just the specific detailed reason that aggregation failed,
8765 /// with minimal context. While this is often enough to diagnose a problem
8766 /// if only a small change was made and the system had been working before
8767 /// the small change, it's often not particularly helpful for getting a new
8768 /// buffer collection to work for the first time. Especially with more
8769 /// complex trees of nodes, involving things like AttachToken(),
8770 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
8771 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
8772 /// looks like and why it's failing a logical allocation, or why a tree or
8773 /// sub-tree is failing sooner than expected.
8774 ///
8775 /// The intent of the extra logging is to be acceptable from a performance
8776 /// point of view, if only enabled on a low number of buffer collections.
8777 /// If we're not tracking down a bug, we shouldn't send this message.
8778 ///
8779 /// If too many participants leave verbose logging enabled, we may end up
8780 /// needing to require that system-wide sysmem verbose logging be permitted
8781 /// via some other setting, to avoid sysmem spamming the log too much due to
8782 /// this message.
8783 ///
8784 /// This may be a NOP for some nodes due to intentional policy associated
8785 /// with the node, if we don't trust a node enough to let it turn on verbose
8786 /// logging.
8787 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
8788 self.client.send::<fidl::encoding::EmptyPayload>(
8789 (),
8790 0x6bfbe2cf1701d288,
8791 fidl::encoding::DynamicFlags::empty(),
8792 )
8793 }
8794
8795 /// This gets an event handle that can be used as a parameter to
8796 /// IsAlternateFor() called on any Node. The client will not be granted the
8797 /// right to signal this event, as this handle should only be used as proof
8798 /// that the client obtained this handle from this Node.
8799 ///
8800 /// Because this is a get not a set, no Sync() is needed between the
8801 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
8802 /// potentially being on different channels.
8803 ///
8804 /// See also IsAlternateFor().
8805 pub fn r#get_node_ref(
8806 &self,
8807 ___deadline: zx::MonotonicInstant,
8808 ) -> Result<fidl::Event, fidl::Error> {
8809 let _response =
8810 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
8811 (),
8812 0x467b7c75c35c3b84,
8813 fidl::encoding::DynamicFlags::empty(),
8814 ___deadline,
8815 )?;
8816 Ok(_response.node_ref)
8817 }
8818
8819 /// This checks whether the calling node is in a subtree rooted at a
8820 /// different child token of a common parent BufferCollectionTokenGroup, in
8821 /// relation to the passed-in node_ref.
8822 ///
8823 /// This call is for assisting with admission control de-duplication, and
8824 /// with debugging.
8825 ///
8826 /// The node_ref must be obtained using GetNodeRef() of a
8827 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
8828 ///
8829 /// The node_ref can be a duplicated handle; it's not necessary to call
8830 /// GetNodeRef() for every call to IsAlternateFor().
8831 ///
8832 /// If a calling token may not actually be a valid token at all due to
8833 /// a potentially hostile/untrusted provider of the token, call
8834 /// ValidateBufferCollectionToken() first instead of potentially getting
8835 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
8836 /// token not being a real token (not really talking to sysmem). Another
8837 /// option is to call BindSharedCollection with this token first which also
8838 /// validates the token along with converting it to a BufferCollection, then
8839 /// call BufferCollection IsAlternateFor().
8840 ///
8841 /// error values:
8842 ///
8843 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
8844 /// buffer collection as the calling Node. Before logical allocation and
8845 /// within the same logical allocation sub-tree, this essentially means that
8846 /// the node_ref was never part of this logical buffer collection, since
8847 /// before logical allocation all node_refs that come into existence remain
8848 /// in existence at least until logical allocation (including Node(s) that
8849 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
8850 /// to be returned, this Node's channel needs to still be connected server
8851 /// side, which won't be the case if the whole logical allocation has
8852 /// failed. After logical allocation or in a different logical allocation
8853 /// sub-tree there are additional potential reasons for this error. For
8854 /// example a different logical allocation (separated from this Node(s)
8855 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
8856 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
8857 /// exist and may select a different child sub-tree than the sub-tree the
8858 /// node_ref is in causing deletion of the node_ref Node. The only time
8859 /// sysmem keeps a Node around after that Node has no corresponding channel
8860 /// is when Close() is used and the Node's sub-tree has not yet failed.
8861 /// Another reason for this error is if the node_ref is an eventpair handle
8862 /// with sufficient rights, but isn't actually a real node_ref obtained from
8863 /// GetNodeRef().
8864 ///
8865 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
8866 /// eventpair handle, or doesn't have the needed rights expected on a real
8867 /// node_ref.
8868 ///
8869 /// No other failing status codes are returned by this call. However,
8870 /// sysmem may add additional codes in future, so the client should have
8871 /// sensible default handling for any failing status code.
8872 ///
8873 /// On success, is_alternate has the following meaning:
8874 /// * true - The first parent node in common between the calling node and
8875 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
8876 /// the calling Node and the node_ref Node will _not_ have both their
8877 /// constraints apply - rather sysmem will choose one or the other of
8878 /// the constraints - never both. This is because only one child of
8879 /// a BufferCollectionTokenGroup is selected during logical allocation,
8880 /// with only that one child's sub-tree contributing to constraints
8881 /// aggregation.
8882 /// * false - The first parent node in common between the calling Node and
8883 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
8884 /// this means the first parent node in common is a
8885 /// BufferCollectionToken or BufferCollection (regardless of not
8886 /// Close()ed or Close()ed). This means that the calling Node and the
8887 /// node_ref Node _may_ have both their constraints apply during
8888 /// constraints aggregation of the logical allocation, if both Node(s)
8889 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
8890 /// In this case, there is no BufferCollectionTokenGroup that will
8891 /// directly prevent the two Node(s) from both being selected and their
8892 /// constraints both aggregated, but even when false, one or both
8893 /// Node(s) may still be eliminated from consideration if one or both
8894 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
8895 /// which selects a child sub-tree other than the sub-tree containing
8896 /// the calling Node or node_ref Node.
8897 pub fn r#is_alternate_for(
8898 &self,
8899 mut node_ref: fidl::Event,
8900 ___deadline: zx::MonotonicInstant,
8901 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
8902 let _response = self.client.send_query::<
8903 NodeIsAlternateForRequest,
8904 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
8905 >(
8906 (node_ref,),
8907 0x33a2a7aff2776c07,
8908 fidl::encoding::DynamicFlags::empty(),
8909 ___deadline,
8910 )?;
8911 Ok(_response.map(|x| x.is_alternate))
8912 }
8913}
8914
8915#[cfg(target_os = "fuchsia")]
8916impl From<NodeSynchronousProxy> for zx::Handle {
8917 fn from(value: NodeSynchronousProxy) -> Self {
8918 value.into_channel().into()
8919 }
8920}
8921
8922#[cfg(target_os = "fuchsia")]
8923impl From<fidl::Channel> for NodeSynchronousProxy {
8924 fn from(value: fidl::Channel) -> Self {
8925 Self::new(value)
8926 }
8927}
8928
8929#[cfg(target_os = "fuchsia")]
8930impl fidl::endpoints::FromClient for NodeSynchronousProxy {
8931 type Protocol = NodeMarker;
8932
8933 fn from_client(value: fidl::endpoints::ClientEnd<NodeMarker>) -> Self {
8934 Self::new(value.into_channel())
8935 }
8936}
8937
8938#[derive(Debug, Clone)]
8939pub struct NodeProxy {
8940 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
8941}
8942
8943impl fidl::endpoints::Proxy for NodeProxy {
8944 type Protocol = NodeMarker;
8945
8946 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
8947 Self::new(inner)
8948 }
8949
8950 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
8951 self.client.into_channel().map_err(|client| Self { client })
8952 }
8953
8954 fn as_channel(&self) -> &::fidl::AsyncChannel {
8955 self.client.as_channel()
8956 }
8957}
8958
8959impl NodeProxy {
8960 /// Create a new Proxy for fuchsia.sysmem/Node.
8961 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
8962 let protocol_name = <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
8963 Self { client: fidl::client::Client::new(channel, protocol_name) }
8964 }
8965
8966 /// Get a Stream of events from the remote end of the protocol.
8967 ///
8968 /// # Panics
8969 ///
8970 /// Panics if the event stream was already taken.
8971 pub fn take_event_stream(&self) -> NodeEventStream {
8972 NodeEventStream { event_receiver: self.client.take_event_receiver() }
8973 }
8974
8975 /// Ensure that previous messages, including Duplicate() messages on a
8976 /// token, collection, or group, have been received server side.
8977 ///
8978 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
8979 /// valid sysmem token risks the Sync() hanging forever. See
8980 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
8981 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
8982 /// Another way is to pass the token to BindSharedCollection(), which also
8983 /// validates the token as part of exchanging it for a BufferCollection
8984 /// channel, and BufferCollection Sync() can then be used.
8985 ///
8986 /// After a Sync(), it's then safe to send the client end of token_request
8987 /// to another participant knowing the server will recognize the token when
8988 /// it's sent into BindSharedCollection() by the other participant.
8989 ///
8990 /// Other options include waiting for each token.Duplicate() to complete
8991 /// individually (using separate call to token.Sync() after each), or
8992 /// calling Sync() on BufferCollection after the token has been turned in
8993 /// via BindSharedCollection().
8994 ///
8995 /// Another way to mitigate is to avoid calling Sync() on the token, and
8996 /// instead later deal with potential failure of BufferCollection.Sync() if
8997 /// the original token was invalid. This option can be preferable from a
8998 /// performance point of view, but requires client code to delay sending
8999 /// tokens duplicated from this token until after client code has converted
9000 /// the duplicating token to a BufferCollection and received successful
9001 /// response from BufferCollection.Sync().
9002 ///
9003 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
9004 /// When BufferCollection.Sync() isn't feasible, the caller must already
9005 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
9006 /// hang forever. See ValidateBufferCollectionToken() to check token
9007 /// validity first if the token isn't already known to be (is/was) valid.
9008 pub fn r#sync(
9009 &self,
9010 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
9011 NodeProxyInterface::r#sync(self)
9012 }
9013
9014 /// On a BufferCollectionToken channel:
9015 ///
9016 /// Normally a participant will convert a BufferCollectionToken into a
9017 /// BufferCollection view, but a participant is also free to Close() the
9018 /// token (and then close the channel immediately or shortly later in
9019 /// response to server closing its end), which avoids causing logical buffer
9020 /// collection failure. Â Normally an unexpected token channel close will
9021 /// cause logical buffer collection failure (the only exceptions being
9022 /// certain cases involving AttachToken() or SetDispensable()).
9023 ///
9024 /// On a BufferCollection channel:
9025 ///
9026 /// By default the server handles unexpected failure of a BufferCollection
9027 /// by failing the whole logical buffer collection. Partly this is to
9028 /// expedite closing VMO handles to reclaim memory when any participant
9029 /// fails. If a participant would like to cleanly close a BufferCollection
9030 /// view without causing logical buffer collection failure, the participant
9031 /// can send Close() before closing the client end of the BufferCollection
9032 /// channel. If this is the last BufferCollection view, the logical buffer
9033 /// collection will still go away. The Close() can occur before or after
9034 /// SetConstraints(). If before SetConstraints(), the buffer collection
9035 /// won't require constraints from this node in order to allocate. If
9036 /// after SetConstraints(), the constraints are retained and aggregated
9037 /// along with any subsequent logical allocation(s), despite the lack of
9038 /// channel connection.
9039 ///
9040 /// On a BufferCollectionTokenGroup channel:
9041 ///
9042 /// By default, unexpected failure of a BufferCollectionTokenGroup will
9043 /// trigger failure of the logical BufferCollectionTokenGroup and will
9044 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
9045 /// channel without failing the logical group or propagating failure, send
9046 /// Close() before closing the channel client endpoint.
9047 ///
9048 /// If Close() occurs before AllChildrenPresent(), the logical buffer
9049 /// collection will still fail despite the Close() (because sysmem can't be
9050 /// sure whether all relevant children were created, so it's ambiguous
9051 /// whether all relevant constraints will be provided to sysmem). If
9052 /// Close() occurs after AllChildrenPresent(), the children and all their
9053 /// constraints remain intact (just as they would if the
9054 /// BufferCollectionTokenGroup channel had remained open), and the close
9055 /// doesn't trigger or propagate failure.
9056 pub fn r#close(&self) -> Result<(), fidl::Error> {
9057 NodeProxyInterface::r#close(self)
9058 }
9059
9060 /// Set a name for VMOs in this buffer collection. The name may be truncated
9061 /// shorter. The name only affects VMOs allocated after it's set - this call
9062 /// does not rename existing VMOs. If multiple clients set different names
9063 /// then the larger priority value will win.
9064 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
9065 NodeProxyInterface::r#set_name(self, priority, name)
9066 }
9067
9068 /// Set information about the current client that can be used by sysmem to
9069 /// help debug leaking memory and hangs waiting for constraints. |name| can
9070 /// be an arbitrary string, but the current process name (see
9071 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
9072 /// arbitrary id, but the current process ID (see
9073 /// fsl::GetCurrentProcessKoid()) is a good default.
9074 ///
9075 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
9076 /// indicate which client is closing their channel first, leading to
9077 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
9078 /// over, but if happening earlier than expected, the
9079 /// client-channel-specific name can help diagnose where the failure is
9080 /// first coming from, from sysmem's point of view).
9081 ///
9082 /// By default (unless overriden by this message or using
9083 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
9084 /// parent Node at the time the child Node is created. While this can be
9085 /// better than nothing, it's often better for each participant to use
9086 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
9087 /// info directly relevant to the current client. Also, SetVerboseLogging()
9088 /// can be used to help disambiguate if a Node is suspected of having info
9089 /// that was copied from its parent.
9090 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
9091 NodeProxyInterface::r#set_debug_client_info(self, name, id)
9092 }
9093
9094 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
9095 /// after creating a collection. Clients can call this method to change
9096 /// when the log is printed. If multiple client set the deadline, it's
9097 /// unspecified which deadline will take effect.
9098 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
9099 NodeProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
9100 }
9101
9102 /// Verbose logging includes constraints set via SetConstraints() from each
9103 /// client along with info set via SetDebugClientInfo() and the structure of
9104 /// the tree of Node(s).
9105 ///
9106 /// Normally sysmem prints only a single line complaint when aggregation
9107 /// fails, with just the specific detailed reason that aggregation failed,
9108 /// with minimal context. While this is often enough to diagnose a problem
9109 /// if only a small change was made and the system had been working before
9110 /// the small change, it's often not particularly helpful for getting a new
9111 /// buffer collection to work for the first time. Especially with more
9112 /// complex trees of nodes, involving things like AttachToken(),
9113 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
9114 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
9115 /// looks like and why it's failing a logical allocation, or why a tree or
9116 /// sub-tree is failing sooner than expected.
9117 ///
9118 /// The intent of the extra logging is to be acceptable from a performance
9119 /// point of view, if only enabled on a low number of buffer collections.
9120 /// If we're not tracking down a bug, we shouldn't send this message.
9121 ///
9122 /// If too many participants leave verbose logging enabled, we may end up
9123 /// needing to require that system-wide sysmem verbose logging be permitted
9124 /// via some other setting, to avoid sysmem spamming the log too much due to
9125 /// this message.
9126 ///
9127 /// This may be a NOP for some nodes due to intentional policy associated
9128 /// with the node, if we don't trust a node enough to let it turn on verbose
9129 /// logging.
9130 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
9131 NodeProxyInterface::r#set_verbose_logging(self)
9132 }
9133
9134 /// This gets an event handle that can be used as a parameter to
9135 /// IsAlternateFor() called on any Node. The client will not be granted the
9136 /// right to signal this event, as this handle should only be used as proof
9137 /// that the client obtained this handle from this Node.
9138 ///
9139 /// Because this is a get not a set, no Sync() is needed between the
9140 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
9141 /// potentially being on different channels.
9142 ///
9143 /// See also IsAlternateFor().
9144 pub fn r#get_node_ref(
9145 &self,
9146 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
9147 {
9148 NodeProxyInterface::r#get_node_ref(self)
9149 }
9150
9151 /// This checks whether the calling node is in a subtree rooted at a
9152 /// different child token of a common parent BufferCollectionTokenGroup, in
9153 /// relation to the passed-in node_ref.
9154 ///
9155 /// This call is for assisting with admission control de-duplication, and
9156 /// with debugging.
9157 ///
9158 /// The node_ref must be obtained using GetNodeRef() of a
9159 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
9160 ///
9161 /// The node_ref can be a duplicated handle; it's not necessary to call
9162 /// GetNodeRef() for every call to IsAlternateFor().
9163 ///
9164 /// If a calling token may not actually be a valid token at all due to
9165 /// a potentially hostile/untrusted provider of the token, call
9166 /// ValidateBufferCollectionToken() first instead of potentially getting
9167 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
9168 /// token not being a real token (not really talking to sysmem). Another
9169 /// option is to call BindSharedCollection with this token first which also
9170 /// validates the token along with converting it to a BufferCollection, then
9171 /// call BufferCollection IsAlternateFor().
9172 ///
9173 /// error values:
9174 ///
9175 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
9176 /// buffer collection as the calling Node. Before logical allocation and
9177 /// within the same logical allocation sub-tree, this essentially means that
9178 /// the node_ref was never part of this logical buffer collection, since
9179 /// before logical allocation all node_refs that come into existence remain
9180 /// in existence at least until logical allocation (including Node(s) that
9181 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
9182 /// to be returned, this Node's channel needs to still be connected server
9183 /// side, which won't be the case if the whole logical allocation has
9184 /// failed. After logical allocation or in a different logical allocation
9185 /// sub-tree there are additional potential reasons for this error. For
9186 /// example a different logical allocation (separated from this Node(s)
9187 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
9188 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
9189 /// exist and may select a different child sub-tree than the sub-tree the
9190 /// node_ref is in causing deletion of the node_ref Node. The only time
9191 /// sysmem keeps a Node around after that Node has no corresponding channel
9192 /// is when Close() is used and the Node's sub-tree has not yet failed.
9193 /// Another reason for this error is if the node_ref is an eventpair handle
9194 /// with sufficient rights, but isn't actually a real node_ref obtained from
9195 /// GetNodeRef().
9196 ///
9197 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
9198 /// eventpair handle, or doesn't have the needed rights expected on a real
9199 /// node_ref.
9200 ///
9201 /// No other failing status codes are returned by this call. However,
9202 /// sysmem may add additional codes in future, so the client should have
9203 /// sensible default handling for any failing status code.
9204 ///
9205 /// On success, is_alternate has the following meaning:
9206 /// * true - The first parent node in common between the calling node and
9207 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
9208 /// the calling Node and the node_ref Node will _not_ have both their
9209 /// constraints apply - rather sysmem will choose one or the other of
9210 /// the constraints - never both. This is because only one child of
9211 /// a BufferCollectionTokenGroup is selected during logical allocation,
9212 /// with only that one child's sub-tree contributing to constraints
9213 /// aggregation.
9214 /// * false - The first parent node in common between the calling Node and
9215 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
9216 /// this means the first parent node in common is a
9217 /// BufferCollectionToken or BufferCollection (regardless of not
9218 /// Close()ed or Close()ed). This means that the calling Node and the
9219 /// node_ref Node _may_ have both their constraints apply during
9220 /// constraints aggregation of the logical allocation, if both Node(s)
9221 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
9222 /// In this case, there is no BufferCollectionTokenGroup that will
9223 /// directly prevent the two Node(s) from both being selected and their
9224 /// constraints both aggregated, but even when false, one or both
9225 /// Node(s) may still be eliminated from consideration if one or both
9226 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
9227 /// which selects a child sub-tree other than the sub-tree containing
9228 /// the calling Node or node_ref Node.
9229 pub fn r#is_alternate_for(
9230 &self,
9231 mut node_ref: fidl::Event,
9232 ) -> fidl::client::QueryResponseFut<
9233 NodeIsAlternateForResult,
9234 fidl::encoding::DefaultFuchsiaResourceDialect,
9235 > {
9236 NodeProxyInterface::r#is_alternate_for(self, node_ref)
9237 }
9238}
9239
9240impl NodeProxyInterface for NodeProxy {
9241 type SyncResponseFut =
9242 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
9243 fn r#sync(&self) -> Self::SyncResponseFut {
9244 fn _decode(
9245 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9246 ) -> Result<(), fidl::Error> {
9247 let _response = fidl::client::decode_transaction_body::<
9248 fidl::encoding::EmptyPayload,
9249 fidl::encoding::DefaultFuchsiaResourceDialect,
9250 0x4577e238ae26291,
9251 >(_buf?)?;
9252 Ok(_response)
9253 }
9254 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
9255 (),
9256 0x4577e238ae26291,
9257 fidl::encoding::DynamicFlags::empty(),
9258 _decode,
9259 )
9260 }
9261
9262 fn r#close(&self) -> Result<(), fidl::Error> {
9263 self.client.send::<fidl::encoding::EmptyPayload>(
9264 (),
9265 0x5b1d7a4f5681fca7,
9266 fidl::encoding::DynamicFlags::empty(),
9267 )
9268 }
9269
9270 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
9271 self.client.send::<NodeSetNameRequest>(
9272 (priority, name),
9273 0x77a41bb6217e2443,
9274 fidl::encoding::DynamicFlags::empty(),
9275 )
9276 }
9277
9278 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
9279 self.client.send::<NodeSetDebugClientInfoRequest>(
9280 (name, id),
9281 0x7275759070eb5ee2,
9282 fidl::encoding::DynamicFlags::empty(),
9283 )
9284 }
9285
9286 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
9287 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
9288 (deadline,),
9289 0x46d38f4772638867,
9290 fidl::encoding::DynamicFlags::empty(),
9291 )
9292 }
9293
9294 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
9295 self.client.send::<fidl::encoding::EmptyPayload>(
9296 (),
9297 0x6bfbe2cf1701d288,
9298 fidl::encoding::DynamicFlags::empty(),
9299 )
9300 }
9301
9302 type GetNodeRefResponseFut =
9303 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
9304 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
9305 fn _decode(
9306 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9307 ) -> Result<fidl::Event, fidl::Error> {
9308 let _response = fidl::client::decode_transaction_body::<
9309 NodeGetNodeRefResponse,
9310 fidl::encoding::DefaultFuchsiaResourceDialect,
9311 0x467b7c75c35c3b84,
9312 >(_buf?)?;
9313 Ok(_response.node_ref)
9314 }
9315 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
9316 (),
9317 0x467b7c75c35c3b84,
9318 fidl::encoding::DynamicFlags::empty(),
9319 _decode,
9320 )
9321 }
9322
9323 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
9324 NodeIsAlternateForResult,
9325 fidl::encoding::DefaultFuchsiaResourceDialect,
9326 >;
9327 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
9328 fn _decode(
9329 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9330 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
9331 let _response = fidl::client::decode_transaction_body::<
9332 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
9333 fidl::encoding::DefaultFuchsiaResourceDialect,
9334 0x33a2a7aff2776c07,
9335 >(_buf?)?;
9336 Ok(_response.map(|x| x.is_alternate))
9337 }
9338 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
9339 (node_ref,),
9340 0x33a2a7aff2776c07,
9341 fidl::encoding::DynamicFlags::empty(),
9342 _decode,
9343 )
9344 }
9345}
9346
9347pub struct NodeEventStream {
9348 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
9349}
9350
9351impl std::marker::Unpin for NodeEventStream {}
9352
9353impl futures::stream::FusedStream for NodeEventStream {
9354 fn is_terminated(&self) -> bool {
9355 self.event_receiver.is_terminated()
9356 }
9357}
9358
9359impl futures::Stream for NodeEventStream {
9360 type Item = Result<NodeEvent, fidl::Error>;
9361
9362 fn poll_next(
9363 mut self: std::pin::Pin<&mut Self>,
9364 cx: &mut std::task::Context<'_>,
9365 ) -> std::task::Poll<Option<Self::Item>> {
9366 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
9367 &mut self.event_receiver,
9368 cx
9369 )?) {
9370 Some(buf) => std::task::Poll::Ready(Some(NodeEvent::decode(buf))),
9371 None => std::task::Poll::Ready(None),
9372 }
9373 }
9374}
9375
9376#[derive(Debug)]
9377pub enum NodeEvent {}
9378
9379impl NodeEvent {
9380 /// Decodes a message buffer as a [`NodeEvent`].
9381 fn decode(
9382 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
9383 ) -> Result<NodeEvent, fidl::Error> {
9384 let (bytes, _handles) = buf.split_mut();
9385 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
9386 debug_assert_eq!(tx_header.tx_id, 0);
9387 match tx_header.ordinal {
9388 _ => Err(fidl::Error::UnknownOrdinal {
9389 ordinal: tx_header.ordinal,
9390 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
9391 }),
9392 }
9393 }
9394}
9395
9396/// A Stream of incoming requests for fuchsia.sysmem/Node.
9397pub struct NodeRequestStream {
9398 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9399 is_terminated: bool,
9400}
9401
9402impl std::marker::Unpin for NodeRequestStream {}
9403
9404impl futures::stream::FusedStream for NodeRequestStream {
9405 fn is_terminated(&self) -> bool {
9406 self.is_terminated
9407 }
9408}
9409
9410impl fidl::endpoints::RequestStream for NodeRequestStream {
9411 type Protocol = NodeMarker;
9412 type ControlHandle = NodeControlHandle;
9413
9414 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
9415 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
9416 }
9417
9418 fn control_handle(&self) -> Self::ControlHandle {
9419 NodeControlHandle { inner: self.inner.clone() }
9420 }
9421
9422 fn into_inner(
9423 self,
9424 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
9425 {
9426 (self.inner, self.is_terminated)
9427 }
9428
9429 fn from_inner(
9430 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9431 is_terminated: bool,
9432 ) -> Self {
9433 Self { inner, is_terminated }
9434 }
9435}
9436
9437impl futures::Stream for NodeRequestStream {
9438 type Item = Result<NodeRequest, fidl::Error>;
9439
9440 fn poll_next(
9441 mut self: std::pin::Pin<&mut Self>,
9442 cx: &mut std::task::Context<'_>,
9443 ) -> std::task::Poll<Option<Self::Item>> {
9444 let this = &mut *self;
9445 if this.inner.check_shutdown(cx) {
9446 this.is_terminated = true;
9447 return std::task::Poll::Ready(None);
9448 }
9449 if this.is_terminated {
9450 panic!("polled NodeRequestStream after completion");
9451 }
9452 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
9453 |bytes, handles| {
9454 match this.inner.channel().read_etc(cx, bytes, handles) {
9455 std::task::Poll::Ready(Ok(())) => {}
9456 std::task::Poll::Pending => return std::task::Poll::Pending,
9457 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
9458 this.is_terminated = true;
9459 return std::task::Poll::Ready(None);
9460 }
9461 std::task::Poll::Ready(Err(e)) => {
9462 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
9463 e.into(),
9464 ))));
9465 }
9466 }
9467
9468 // A message has been received from the channel
9469 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
9470
9471 std::task::Poll::Ready(Some(match header.ordinal {
9472 0x4577e238ae26291 => {
9473 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9474 let mut req = fidl::new_empty!(
9475 fidl::encoding::EmptyPayload,
9476 fidl::encoding::DefaultFuchsiaResourceDialect
9477 );
9478 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9479 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9480 Ok(NodeRequest::Sync {
9481 responder: NodeSyncResponder {
9482 control_handle: std::mem::ManuallyDrop::new(control_handle),
9483 tx_id: header.tx_id,
9484 },
9485 })
9486 }
9487 0x5b1d7a4f5681fca7 => {
9488 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9489 let mut req = fidl::new_empty!(
9490 fidl::encoding::EmptyPayload,
9491 fidl::encoding::DefaultFuchsiaResourceDialect
9492 );
9493 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9494 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9495 Ok(NodeRequest::Close { control_handle })
9496 }
9497 0x77a41bb6217e2443 => {
9498 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9499 let mut req = fidl::new_empty!(
9500 NodeSetNameRequest,
9501 fidl::encoding::DefaultFuchsiaResourceDialect
9502 );
9503 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
9504 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9505 Ok(NodeRequest::SetName {
9506 priority: req.priority,
9507 name: req.name,
9508
9509 control_handle,
9510 })
9511 }
9512 0x7275759070eb5ee2 => {
9513 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9514 let mut req = fidl::new_empty!(
9515 NodeSetDebugClientInfoRequest,
9516 fidl::encoding::DefaultFuchsiaResourceDialect
9517 );
9518 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
9519 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9520 Ok(NodeRequest::SetDebugClientInfo {
9521 name: req.name,
9522 id: req.id,
9523
9524 control_handle,
9525 })
9526 }
9527 0x46d38f4772638867 => {
9528 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9529 let mut req = fidl::new_empty!(
9530 NodeSetDebugTimeoutLogDeadlineRequest,
9531 fidl::encoding::DefaultFuchsiaResourceDialect
9532 );
9533 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
9534 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9535 Ok(NodeRequest::SetDebugTimeoutLogDeadline {
9536 deadline: req.deadline,
9537
9538 control_handle,
9539 })
9540 }
9541 0x6bfbe2cf1701d288 => {
9542 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9543 let mut req = fidl::new_empty!(
9544 fidl::encoding::EmptyPayload,
9545 fidl::encoding::DefaultFuchsiaResourceDialect
9546 );
9547 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9548 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9549 Ok(NodeRequest::SetVerboseLogging { control_handle })
9550 }
9551 0x467b7c75c35c3b84 => {
9552 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9553 let mut req = fidl::new_empty!(
9554 fidl::encoding::EmptyPayload,
9555 fidl::encoding::DefaultFuchsiaResourceDialect
9556 );
9557 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9558 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9559 Ok(NodeRequest::GetNodeRef {
9560 responder: NodeGetNodeRefResponder {
9561 control_handle: std::mem::ManuallyDrop::new(control_handle),
9562 tx_id: header.tx_id,
9563 },
9564 })
9565 }
9566 0x33a2a7aff2776c07 => {
9567 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9568 let mut req = fidl::new_empty!(
9569 NodeIsAlternateForRequest,
9570 fidl::encoding::DefaultFuchsiaResourceDialect
9571 );
9572 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
9573 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9574 Ok(NodeRequest::IsAlternateFor {
9575 node_ref: req.node_ref,
9576
9577 responder: NodeIsAlternateForResponder {
9578 control_handle: std::mem::ManuallyDrop::new(control_handle),
9579 tx_id: header.tx_id,
9580 },
9581 })
9582 }
9583 _ => Err(fidl::Error::UnknownOrdinal {
9584 ordinal: header.ordinal,
9585 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
9586 }),
9587 }))
9588 },
9589 )
9590 }
9591}
9592
9593#[derive(Debug)]
9594pub enum NodeRequest {
9595 /// Ensure that previous messages, including Duplicate() messages on a
9596 /// token, collection, or group, have been received server side.
9597 ///
9598 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
9599 /// valid sysmem token risks the Sync() hanging forever. See
9600 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
9601 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
9602 /// Another way is to pass the token to BindSharedCollection(), which also
9603 /// validates the token as part of exchanging it for a BufferCollection
9604 /// channel, and BufferCollection Sync() can then be used.
9605 ///
9606 /// After a Sync(), it's then safe to send the client end of token_request
9607 /// to another participant knowing the server will recognize the token when
9608 /// it's sent into BindSharedCollection() by the other participant.
9609 ///
9610 /// Other options include waiting for each token.Duplicate() to complete
9611 /// individually (using separate call to token.Sync() after each), or
9612 /// calling Sync() on BufferCollection after the token has been turned in
9613 /// via BindSharedCollection().
9614 ///
9615 /// Another way to mitigate is to avoid calling Sync() on the token, and
9616 /// instead later deal with potential failure of BufferCollection.Sync() if
9617 /// the original token was invalid. This option can be preferable from a
9618 /// performance point of view, but requires client code to delay sending
9619 /// tokens duplicated from this token until after client code has converted
9620 /// the duplicating token to a BufferCollection and received successful
9621 /// response from BufferCollection.Sync().
9622 ///
9623 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
9624 /// When BufferCollection.Sync() isn't feasible, the caller must already
9625 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
9626 /// hang forever. See ValidateBufferCollectionToken() to check token
9627 /// validity first if the token isn't already known to be (is/was) valid.
9628 Sync { responder: NodeSyncResponder },
9629 /// On a BufferCollectionToken channel:
9630 ///
9631 /// Normally a participant will convert a BufferCollectionToken into a
9632 /// BufferCollection view, but a participant is also free to Close() the
9633 /// token (and then close the channel immediately or shortly later in
9634 /// response to server closing its end), which avoids causing logical buffer
9635 /// collection failure. Â Normally an unexpected token channel close will
9636 /// cause logical buffer collection failure (the only exceptions being
9637 /// certain cases involving AttachToken() or SetDispensable()).
9638 ///
9639 /// On a BufferCollection channel:
9640 ///
9641 /// By default the server handles unexpected failure of a BufferCollection
9642 /// by failing the whole logical buffer collection. Partly this is to
9643 /// expedite closing VMO handles to reclaim memory when any participant
9644 /// fails. If a participant would like to cleanly close a BufferCollection
9645 /// view without causing logical buffer collection failure, the participant
9646 /// can send Close() before closing the client end of the BufferCollection
9647 /// channel. If this is the last BufferCollection view, the logical buffer
9648 /// collection will still go away. The Close() can occur before or after
9649 /// SetConstraints(). If before SetConstraints(), the buffer collection
9650 /// won't require constraints from this node in order to allocate. If
9651 /// after SetConstraints(), the constraints are retained and aggregated
9652 /// along with any subsequent logical allocation(s), despite the lack of
9653 /// channel connection.
9654 ///
9655 /// On a BufferCollectionTokenGroup channel:
9656 ///
9657 /// By default, unexpected failure of a BufferCollectionTokenGroup will
9658 /// trigger failure of the logical BufferCollectionTokenGroup and will
9659 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
9660 /// channel without failing the logical group or propagating failure, send
9661 /// Close() before closing the channel client endpoint.
9662 ///
9663 /// If Close() occurs before AllChildrenPresent(), the logical buffer
9664 /// collection will still fail despite the Close() (because sysmem can't be
9665 /// sure whether all relevant children were created, so it's ambiguous
9666 /// whether all relevant constraints will be provided to sysmem). If
9667 /// Close() occurs after AllChildrenPresent(), the children and all their
9668 /// constraints remain intact (just as they would if the
9669 /// BufferCollectionTokenGroup channel had remained open), and the close
9670 /// doesn't trigger or propagate failure.
9671 Close { control_handle: NodeControlHandle },
9672 /// Set a name for VMOs in this buffer collection. The name may be truncated
9673 /// shorter. The name only affects VMOs allocated after it's set - this call
9674 /// does not rename existing VMOs. If multiple clients set different names
9675 /// then the larger priority value will win.
9676 SetName { priority: u32, name: String, control_handle: NodeControlHandle },
9677 /// Set information about the current client that can be used by sysmem to
9678 /// help debug leaking memory and hangs waiting for constraints. |name| can
9679 /// be an arbitrary string, but the current process name (see
9680 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
9681 /// arbitrary id, but the current process ID (see
9682 /// fsl::GetCurrentProcessKoid()) is a good default.
9683 ///
9684 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
9685 /// indicate which client is closing their channel first, leading to
9686 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
9687 /// over, but if happening earlier than expected, the
9688 /// client-channel-specific name can help diagnose where the failure is
9689 /// first coming from, from sysmem's point of view).
9690 ///
9691 /// By default (unless overriden by this message or using
9692 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
9693 /// parent Node at the time the child Node is created. While this can be
9694 /// better than nothing, it's often better for each participant to use
9695 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
9696 /// info directly relevant to the current client. Also, SetVerboseLogging()
9697 /// can be used to help disambiguate if a Node is suspected of having info
9698 /// that was copied from its parent.
9699 SetDebugClientInfo { name: String, id: u64, control_handle: NodeControlHandle },
9700 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
9701 /// after creating a collection. Clients can call this method to change
9702 /// when the log is printed. If multiple client set the deadline, it's
9703 /// unspecified which deadline will take effect.
9704 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: NodeControlHandle },
9705 /// Verbose logging includes constraints set via SetConstraints() from each
9706 /// client along with info set via SetDebugClientInfo() and the structure of
9707 /// the tree of Node(s).
9708 ///
9709 /// Normally sysmem prints only a single line complaint when aggregation
9710 /// fails, with just the specific detailed reason that aggregation failed,
9711 /// with minimal context. While this is often enough to diagnose a problem
9712 /// if only a small change was made and the system had been working before
9713 /// the small change, it's often not particularly helpful for getting a new
9714 /// buffer collection to work for the first time. Especially with more
9715 /// complex trees of nodes, involving things like AttachToken(),
9716 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
9717 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
9718 /// looks like and why it's failing a logical allocation, or why a tree or
9719 /// sub-tree is failing sooner than expected.
9720 ///
9721 /// The intent of the extra logging is to be acceptable from a performance
9722 /// point of view, if only enabled on a low number of buffer collections.
9723 /// If we're not tracking down a bug, we shouldn't send this message.
9724 ///
9725 /// If too many participants leave verbose logging enabled, we may end up
9726 /// needing to require that system-wide sysmem verbose logging be permitted
9727 /// via some other setting, to avoid sysmem spamming the log too much due to
9728 /// this message.
9729 ///
9730 /// This may be a NOP for some nodes due to intentional policy associated
9731 /// with the node, if we don't trust a node enough to let it turn on verbose
9732 /// logging.
9733 SetVerboseLogging { control_handle: NodeControlHandle },
9734 /// This gets an event handle that can be used as a parameter to
9735 /// IsAlternateFor() called on any Node. The client will not be granted the
9736 /// right to signal this event, as this handle should only be used as proof
9737 /// that the client obtained this handle from this Node.
9738 ///
9739 /// Because this is a get not a set, no Sync() is needed between the
9740 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
9741 /// potentially being on different channels.
9742 ///
9743 /// See also IsAlternateFor().
9744 GetNodeRef { responder: NodeGetNodeRefResponder },
9745 /// This checks whether the calling node is in a subtree rooted at a
9746 /// different child token of a common parent BufferCollectionTokenGroup, in
9747 /// relation to the passed-in node_ref.
9748 ///
9749 /// This call is for assisting with admission control de-duplication, and
9750 /// with debugging.
9751 ///
9752 /// The node_ref must be obtained using GetNodeRef() of a
9753 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
9754 ///
9755 /// The node_ref can be a duplicated handle; it's not necessary to call
9756 /// GetNodeRef() for every call to IsAlternateFor().
9757 ///
9758 /// If a calling token may not actually be a valid token at all due to
9759 /// a potentially hostile/untrusted provider of the token, call
9760 /// ValidateBufferCollectionToken() first instead of potentially getting
9761 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
9762 /// token not being a real token (not really talking to sysmem). Another
9763 /// option is to call BindSharedCollection with this token first which also
9764 /// validates the token along with converting it to a BufferCollection, then
9765 /// call BufferCollection IsAlternateFor().
9766 ///
9767 /// error values:
9768 ///
9769 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
9770 /// buffer collection as the calling Node. Before logical allocation and
9771 /// within the same logical allocation sub-tree, this essentially means that
9772 /// the node_ref was never part of this logical buffer collection, since
9773 /// before logical allocation all node_refs that come into existence remain
9774 /// in existence at least until logical allocation (including Node(s) that
9775 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
9776 /// to be returned, this Node's channel needs to still be connected server
9777 /// side, which won't be the case if the whole logical allocation has
9778 /// failed. After logical allocation or in a different logical allocation
9779 /// sub-tree there are additional potential reasons for this error. For
9780 /// example a different logical allocation (separated from this Node(s)
9781 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
9782 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
9783 /// exist and may select a different child sub-tree than the sub-tree the
9784 /// node_ref is in causing deletion of the node_ref Node. The only time
9785 /// sysmem keeps a Node around after that Node has no corresponding channel
9786 /// is when Close() is used and the Node's sub-tree has not yet failed.
9787 /// Another reason for this error is if the node_ref is an eventpair handle
9788 /// with sufficient rights, but isn't actually a real node_ref obtained from
9789 /// GetNodeRef().
9790 ///
9791 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
9792 /// eventpair handle, or doesn't have the needed rights expected on a real
9793 /// node_ref.
9794 ///
9795 /// No other failing status codes are returned by this call. However,
9796 /// sysmem may add additional codes in future, so the client should have
9797 /// sensible default handling for any failing status code.
9798 ///
9799 /// On success, is_alternate has the following meaning:
9800 /// * true - The first parent node in common between the calling node and
9801 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
9802 /// the calling Node and the node_ref Node will _not_ have both their
9803 /// constraints apply - rather sysmem will choose one or the other of
9804 /// the constraints - never both. This is because only one child of
9805 /// a BufferCollectionTokenGroup is selected during logical allocation,
9806 /// with only that one child's sub-tree contributing to constraints
9807 /// aggregation.
9808 /// * false - The first parent node in common between the calling Node and
9809 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
9810 /// this means the first parent node in common is a
9811 /// BufferCollectionToken or BufferCollection (regardless of not
9812 /// Close()ed or Close()ed). This means that the calling Node and the
9813 /// node_ref Node _may_ have both their constraints apply during
9814 /// constraints aggregation of the logical allocation, if both Node(s)
9815 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
9816 /// In this case, there is no BufferCollectionTokenGroup that will
9817 /// directly prevent the two Node(s) from both being selected and their
9818 /// constraints both aggregated, but even when false, one or both
9819 /// Node(s) may still be eliminated from consideration if one or both
9820 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
9821 /// which selects a child sub-tree other than the sub-tree containing
9822 /// the calling Node or node_ref Node.
9823 IsAlternateFor { node_ref: fidl::Event, responder: NodeIsAlternateForResponder },
9824}
9825
9826impl NodeRequest {
9827 #[allow(irrefutable_let_patterns)]
9828 pub fn into_sync(self) -> Option<(NodeSyncResponder)> {
9829 if let NodeRequest::Sync { responder } = self { Some((responder)) } else { None }
9830 }
9831
9832 #[allow(irrefutable_let_patterns)]
9833 pub fn into_close(self) -> Option<(NodeControlHandle)> {
9834 if let NodeRequest::Close { control_handle } = self { Some((control_handle)) } else { None }
9835 }
9836
9837 #[allow(irrefutable_let_patterns)]
9838 pub fn into_set_name(self) -> Option<(u32, String, NodeControlHandle)> {
9839 if let NodeRequest::SetName { priority, name, control_handle } = self {
9840 Some((priority, name, control_handle))
9841 } else {
9842 None
9843 }
9844 }
9845
9846 #[allow(irrefutable_let_patterns)]
9847 pub fn into_set_debug_client_info(self) -> Option<(String, u64, NodeControlHandle)> {
9848 if let NodeRequest::SetDebugClientInfo { name, id, control_handle } = self {
9849 Some((name, id, control_handle))
9850 } else {
9851 None
9852 }
9853 }
9854
9855 #[allow(irrefutable_let_patterns)]
9856 pub fn into_set_debug_timeout_log_deadline(self) -> Option<(i64, NodeControlHandle)> {
9857 if let NodeRequest::SetDebugTimeoutLogDeadline { deadline, control_handle } = self {
9858 Some((deadline, control_handle))
9859 } else {
9860 None
9861 }
9862 }
9863
9864 #[allow(irrefutable_let_patterns)]
9865 pub fn into_set_verbose_logging(self) -> Option<(NodeControlHandle)> {
9866 if let NodeRequest::SetVerboseLogging { control_handle } = self {
9867 Some((control_handle))
9868 } else {
9869 None
9870 }
9871 }
9872
9873 #[allow(irrefutable_let_patterns)]
9874 pub fn into_get_node_ref(self) -> Option<(NodeGetNodeRefResponder)> {
9875 if let NodeRequest::GetNodeRef { responder } = self { Some((responder)) } else { None }
9876 }
9877
9878 #[allow(irrefutable_let_patterns)]
9879 pub fn into_is_alternate_for(self) -> Option<(fidl::Event, NodeIsAlternateForResponder)> {
9880 if let NodeRequest::IsAlternateFor { node_ref, responder } = self {
9881 Some((node_ref, responder))
9882 } else {
9883 None
9884 }
9885 }
9886
9887 /// Name of the method defined in FIDL
9888 pub fn method_name(&self) -> &'static str {
9889 match *self {
9890 NodeRequest::Sync { .. } => "sync",
9891 NodeRequest::Close { .. } => "close",
9892 NodeRequest::SetName { .. } => "set_name",
9893 NodeRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
9894 NodeRequest::SetDebugTimeoutLogDeadline { .. } => "set_debug_timeout_log_deadline",
9895 NodeRequest::SetVerboseLogging { .. } => "set_verbose_logging",
9896 NodeRequest::GetNodeRef { .. } => "get_node_ref",
9897 NodeRequest::IsAlternateFor { .. } => "is_alternate_for",
9898 }
9899 }
9900}
9901
9902#[derive(Debug, Clone)]
9903pub struct NodeControlHandle {
9904 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9905}
9906
9907impl fidl::endpoints::ControlHandle for NodeControlHandle {
9908 fn shutdown(&self) {
9909 self.inner.shutdown()
9910 }
9911 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
9912 self.inner.shutdown_with_epitaph(status)
9913 }
9914
9915 fn is_closed(&self) -> bool {
9916 self.inner.channel().is_closed()
9917 }
9918 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
9919 self.inner.channel().on_closed()
9920 }
9921
9922 #[cfg(target_os = "fuchsia")]
9923 fn signal_peer(
9924 &self,
9925 clear_mask: zx::Signals,
9926 set_mask: zx::Signals,
9927 ) -> Result<(), zx_status::Status> {
9928 use fidl::Peered;
9929 self.inner.channel().signal_peer(clear_mask, set_mask)
9930 }
9931}
9932
9933impl NodeControlHandle {}
9934
9935#[must_use = "FIDL methods require a response to be sent"]
9936#[derive(Debug)]
9937pub struct NodeSyncResponder {
9938 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
9939 tx_id: u32,
9940}
9941
9942/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
9943/// if the responder is dropped without sending a response, so that the client
9944/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9945impl std::ops::Drop for NodeSyncResponder {
9946 fn drop(&mut self) {
9947 self.control_handle.shutdown();
9948 // Safety: drops once, never accessed again
9949 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9950 }
9951}
9952
9953impl fidl::endpoints::Responder for NodeSyncResponder {
9954 type ControlHandle = NodeControlHandle;
9955
9956 fn control_handle(&self) -> &NodeControlHandle {
9957 &self.control_handle
9958 }
9959
9960 fn drop_without_shutdown(mut self) {
9961 // Safety: drops once, never accessed again due to mem::forget
9962 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9963 // Prevent Drop from running (which would shut down the channel)
9964 std::mem::forget(self);
9965 }
9966}
9967
9968impl NodeSyncResponder {
9969 /// Sends a response to the FIDL transaction.
9970 ///
9971 /// Sets the channel to shutdown if an error occurs.
9972 pub fn send(self) -> Result<(), fidl::Error> {
9973 let _result = self.send_raw();
9974 if _result.is_err() {
9975 self.control_handle.shutdown();
9976 }
9977 self.drop_without_shutdown();
9978 _result
9979 }
9980
9981 /// Similar to "send" but does not shutdown the channel if an error occurs.
9982 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
9983 let _result = self.send_raw();
9984 self.drop_without_shutdown();
9985 _result
9986 }
9987
9988 fn send_raw(&self) -> Result<(), fidl::Error> {
9989 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
9990 (),
9991 self.tx_id,
9992 0x4577e238ae26291,
9993 fidl::encoding::DynamicFlags::empty(),
9994 )
9995 }
9996}
9997
9998#[must_use = "FIDL methods require a response to be sent"]
9999#[derive(Debug)]
10000pub struct NodeGetNodeRefResponder {
10001 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
10002 tx_id: u32,
10003}
10004
10005/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
10006/// if the responder is dropped without sending a response, so that the client
10007/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
10008impl std::ops::Drop for NodeGetNodeRefResponder {
10009 fn drop(&mut self) {
10010 self.control_handle.shutdown();
10011 // Safety: drops once, never accessed again
10012 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10013 }
10014}
10015
10016impl fidl::endpoints::Responder for NodeGetNodeRefResponder {
10017 type ControlHandle = NodeControlHandle;
10018
10019 fn control_handle(&self) -> &NodeControlHandle {
10020 &self.control_handle
10021 }
10022
10023 fn drop_without_shutdown(mut self) {
10024 // Safety: drops once, never accessed again due to mem::forget
10025 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10026 // Prevent Drop from running (which would shut down the channel)
10027 std::mem::forget(self);
10028 }
10029}
10030
10031impl NodeGetNodeRefResponder {
10032 /// Sends a response to the FIDL transaction.
10033 ///
10034 /// Sets the channel to shutdown if an error occurs.
10035 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10036 let _result = self.send_raw(node_ref);
10037 if _result.is_err() {
10038 self.control_handle.shutdown();
10039 }
10040 self.drop_without_shutdown();
10041 _result
10042 }
10043
10044 /// Similar to "send" but does not shutdown the channel if an error occurs.
10045 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10046 let _result = self.send_raw(node_ref);
10047 self.drop_without_shutdown();
10048 _result
10049 }
10050
10051 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10052 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
10053 (node_ref,),
10054 self.tx_id,
10055 0x467b7c75c35c3b84,
10056 fidl::encoding::DynamicFlags::empty(),
10057 )
10058 }
10059}
10060
10061#[must_use = "FIDL methods require a response to be sent"]
10062#[derive(Debug)]
10063pub struct NodeIsAlternateForResponder {
10064 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
10065 tx_id: u32,
10066}
10067
10068/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
10069/// if the responder is dropped without sending a response, so that the client
10070/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
10071impl std::ops::Drop for NodeIsAlternateForResponder {
10072 fn drop(&mut self) {
10073 self.control_handle.shutdown();
10074 // Safety: drops once, never accessed again
10075 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10076 }
10077}
10078
10079impl fidl::endpoints::Responder for NodeIsAlternateForResponder {
10080 type ControlHandle = NodeControlHandle;
10081
10082 fn control_handle(&self) -> &NodeControlHandle {
10083 &self.control_handle
10084 }
10085
10086 fn drop_without_shutdown(mut self) {
10087 // Safety: drops once, never accessed again due to mem::forget
10088 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10089 // Prevent Drop from running (which would shut down the channel)
10090 std::mem::forget(self);
10091 }
10092}
10093
10094impl NodeIsAlternateForResponder {
10095 /// Sends a response to the FIDL transaction.
10096 ///
10097 /// Sets the channel to shutdown if an error occurs.
10098 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10099 let _result = self.send_raw(result);
10100 if _result.is_err() {
10101 self.control_handle.shutdown();
10102 }
10103 self.drop_without_shutdown();
10104 _result
10105 }
10106
10107 /// Similar to "send" but does not shutdown the channel if an error occurs.
10108 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10109 let _result = self.send_raw(result);
10110 self.drop_without_shutdown();
10111 _result
10112 }
10113
10114 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10115 self.control_handle
10116 .inner
10117 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
10118 result.map(|is_alternate| (is_alternate,)),
10119 self.tx_id,
10120 0x33a2a7aff2776c07,
10121 fidl::encoding::DynamicFlags::empty(),
10122 )
10123 }
10124}
10125
10126#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
10127pub struct SecureMemMarker;
10128
10129impl fidl::endpoints::ProtocolMarker for SecureMemMarker {
10130 type Proxy = SecureMemProxy;
10131 type RequestStream = SecureMemRequestStream;
10132 #[cfg(target_os = "fuchsia")]
10133 type SynchronousProxy = SecureMemSynchronousProxy;
10134
10135 const DEBUG_NAME: &'static str = "(anonymous) SecureMem";
10136}
10137pub type SecureMemGetPhysicalSecureHeapsResult = Result<SecureHeapsAndRanges, i32>;
10138pub type SecureMemGetPhysicalSecureHeapPropertiesResult = Result<SecureHeapProperties, i32>;
10139pub type SecureMemAddSecureHeapPhysicalRangeResult = Result<(), i32>;
10140pub type SecureMemDeleteSecureHeapPhysicalRangeResult = Result<(), i32>;
10141pub type SecureMemModifySecureHeapPhysicalRangeResult = Result<(), i32>;
10142pub type SecureMemZeroSubRangeResult = Result<(), i32>;
10143
10144pub trait SecureMemProxyInterface: Send + Sync {
10145 type GetPhysicalSecureHeapsResponseFut: std::future::Future<Output = Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error>>
10146 + Send;
10147 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut;
10148 type GetPhysicalSecureHeapPropertiesResponseFut: std::future::Future<
10149 Output = Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error>,
10150 > + Send;
10151 fn r#get_physical_secure_heap_properties(
10152 &self,
10153 entire_heap: &SecureHeapAndRange,
10154 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut;
10155 type AddSecureHeapPhysicalRangeResponseFut: std::future::Future<Output = Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error>>
10156 + Send;
10157 fn r#add_secure_heap_physical_range(
10158 &self,
10159 heap_range: &SecureHeapAndRange,
10160 ) -> Self::AddSecureHeapPhysicalRangeResponseFut;
10161 type DeleteSecureHeapPhysicalRangeResponseFut: std::future::Future<
10162 Output = Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error>,
10163 > + Send;
10164 fn r#delete_secure_heap_physical_range(
10165 &self,
10166 heap_range: &SecureHeapAndRange,
10167 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut;
10168 type ModifySecureHeapPhysicalRangeResponseFut: std::future::Future<
10169 Output = Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error>,
10170 > + Send;
10171 fn r#modify_secure_heap_physical_range(
10172 &self,
10173 range_modification: &SecureHeapAndRangeModification,
10174 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut;
10175 type ZeroSubRangeResponseFut: std::future::Future<Output = Result<SecureMemZeroSubRangeResult, fidl::Error>>
10176 + Send;
10177 fn r#zero_sub_range(
10178 &self,
10179 is_covering_range_explicit: bool,
10180 heap_range: &SecureHeapAndRange,
10181 ) -> Self::ZeroSubRangeResponseFut;
10182}
10183#[derive(Debug)]
10184#[cfg(target_os = "fuchsia")]
10185pub struct SecureMemSynchronousProxy {
10186 client: fidl::client::sync::Client,
10187}
10188
10189#[cfg(target_os = "fuchsia")]
10190impl fidl::endpoints::SynchronousProxy for SecureMemSynchronousProxy {
10191 type Proxy = SecureMemProxy;
10192 type Protocol = SecureMemMarker;
10193
10194 fn from_channel(inner: fidl::Channel) -> Self {
10195 Self::new(inner)
10196 }
10197
10198 fn into_channel(self) -> fidl::Channel {
10199 self.client.into_channel()
10200 }
10201
10202 fn as_channel(&self) -> &fidl::Channel {
10203 self.client.as_channel()
10204 }
10205}
10206
10207#[cfg(target_os = "fuchsia")]
10208impl SecureMemSynchronousProxy {
10209 pub fn new(channel: fidl::Channel) -> Self {
10210 let protocol_name = <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
10211 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
10212 }
10213
10214 pub fn into_channel(self) -> fidl::Channel {
10215 self.client.into_channel()
10216 }
10217
10218 /// Waits until an event arrives and returns it. It is safe for other
10219 /// threads to make concurrent requests while waiting for an event.
10220 pub fn wait_for_event(
10221 &self,
10222 deadline: zx::MonotonicInstant,
10223 ) -> Result<SecureMemEvent, fidl::Error> {
10224 SecureMemEvent::decode(self.client.wait_for_event(deadline)?)
10225 }
10226
10227 /// Gets the physical address and length of any secure heap whose physical
10228 /// range is configured via the TEE.
10229 ///
10230 /// Presently, these will be fixed physical addresses and lengths, with the
10231 /// location plumbed via the TEE.
10232 ///
10233 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
10234 /// when there isn't any special heap-specific per-VMO setup or teardown
10235 /// required.
10236 ///
10237 /// The physical range must be secured/protected by the TEE before the
10238 /// securemem driver responds to this request with success.
10239 ///
10240 /// Sysmem should only call this once. Returning zero heaps is not a
10241 /// failure.
10242 ///
10243 /// Errors:
10244 /// * ZX_ERR_BAD_STATE - called more than once.
10245 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10246 /// with TEE which doesn't generate zx_status_t errors).
10247 /// * other errors are allowed; any other errors should be treated the same
10248 /// as ZX_ERR_INTERNAL.
10249 pub fn r#get_physical_secure_heaps(
10250 &self,
10251 ___deadline: zx::MonotonicInstant,
10252 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
10253 let _response = self.client.send_query::<
10254 fidl::encoding::EmptyPayload,
10255 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapsResponse, i32>,
10256 >(
10257 (),
10258 0x782319d6ce7fa05,
10259 fidl::encoding::DynamicFlags::empty(),
10260 ___deadline,
10261 )?;
10262 Ok(_response.map(|x| x.heaps))
10263 }
10264
10265 /// This request from sysmem to the securemem driver gets the properties of
10266 /// a protected/secure heap.
10267 ///
10268 /// This only handles heaps with a single contiguous physical extent.
10269 ///
10270 /// The heap's entire physical range is indicated in case this request needs
10271 /// some physical space to auto-detect how many ranges are REE-usable. Any
10272 /// temporary HW protection ranges will be deleted before this request
10273 /// completes.
10274 pub fn r#get_physical_secure_heap_properties(
10275 &self,
10276 mut entire_heap: &SecureHeapAndRange,
10277 ___deadline: zx::MonotonicInstant,
10278 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
10279 let _response = self.client.send_query::<
10280 SecureMemGetPhysicalSecureHeapPropertiesRequest,
10281 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapPropertiesResponse, i32>,
10282 >(
10283 (entire_heap,),
10284 0x26404e23f1271214,
10285 fidl::encoding::DynamicFlags::empty(),
10286 ___deadline,
10287 )?;
10288 Ok(_response.map(|x| x.properties))
10289 }
10290
10291 /// This request from sysmem to the securemem driver conveys a physical
10292 /// range to add, for a heap whose physical range(s) are set up via
10293 /// sysmem.
10294 ///
10295 /// Only sysmem can call this because only sysmem is handed the client end
10296 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10297 /// securemem driver is the server end of this protocol.
10298 ///
10299 /// The securemem driver must configure all the covered offsets as protected
10300 /// before responding to this message with success.
10301 ///
10302 /// On failure, the securemem driver must ensure the protected range was not
10303 /// created.
10304 ///
10305 /// Sysmem must only call this up to once if dynamic_protection_ranges
10306 /// false.
10307 ///
10308 /// If dynamic_protection_ranges is true, sysmem can call this multiple
10309 /// times as long as the current number of ranges never exceeds
10310 /// max_protected_range_count.
10311 ///
10312 /// The caller must not attempt to add a range that matches an
10313 /// already-existing range. Added ranges can overlap each other as long as
10314 /// no two ranges match exactly.
10315 ///
10316 /// Errors:
10317 /// * ZX_ERR_BAD_STATE - called more than once when
10318 /// !dynamic_protection_ranges. Adding a heap that would cause overall
10319 /// heap count to exceed max_protected_range_count.
10320 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10321 /// to protected_range_granularity.
10322 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10323 /// with TEE which doesn't generate zx_status_t errors).
10324 /// * other errors are possible, such as from communication failures or
10325 /// server propagation of zx_status_t failures.
10326 pub fn r#add_secure_heap_physical_range(
10327 &self,
10328 mut heap_range: &SecureHeapAndRange,
10329 ___deadline: zx::MonotonicInstant,
10330 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
10331 let _response = self.client.send_query::<
10332 SecureMemAddSecureHeapPhysicalRangeRequest,
10333 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10334 >(
10335 (heap_range,),
10336 0x1ca1abcee8a0b33e,
10337 fidl::encoding::DynamicFlags::empty(),
10338 ___deadline,
10339 )?;
10340 Ok(_response.map(|x| x))
10341 }
10342
10343 /// This request from sysmem to the securemem driver conveys a physical
10344 /// range to delete, for a heap whose physical range(s) are set up via
10345 /// sysmem.
10346 ///
10347 /// Only sysmem can call this because only sysmem is handed the client end
10348 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10349 /// securemem driver is the server end of this protocol.
10350 ///
10351 /// The securemem driver must configure all the covered offsets as not
10352 /// protected before responding to this message with success.
10353 ///
10354 /// On failure, the securemem driver must ensure the protected range was not
10355 /// deleted.
10356 ///
10357 /// Sysmem must not call this if dynamic_protection_ranges false.
10358 ///
10359 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10360 /// on various ranges that exist at the time of the call.
10361 ///
10362 /// If any portion of the range being deleted is not also covered by another
10363 /// protected range, then any ongoing DMA to any part of the entire range
10364 /// may be interrupted / may fail, potentially in a way that's disruptive to
10365 /// the entire system (bus lockup or similar, depending on device details).
10366 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
10367 /// any portion of the range being deleted, unless the caller has other
10368 /// active ranges covering every block of the range being deleted. Ongoing
10369 /// DMA to/from blocks outside the range being deleted is never impacted by
10370 /// the deletion.
10371 ///
10372 /// Errors:
10373 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10374 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10375 /// to protected_range_granularity.
10376 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10377 /// with TEE which doesn't generate zx_status_t errors).
10378 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10379 /// * other errors are possible, such as from communication failures or
10380 /// server propagation of zx_status_t failures.
10381 pub fn r#delete_secure_heap_physical_range(
10382 &self,
10383 mut heap_range: &SecureHeapAndRange,
10384 ___deadline: zx::MonotonicInstant,
10385 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
10386 let _response = self.client.send_query::<
10387 SecureMemDeleteSecureHeapPhysicalRangeRequest,
10388 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10389 >(
10390 (heap_range,),
10391 0x728a953e56df92ee,
10392 fidl::encoding::DynamicFlags::empty(),
10393 ___deadline,
10394 )?;
10395 Ok(_response.map(|x| x))
10396 }
10397
10398 /// This request from sysmem to the securemem driver conveys a physical
10399 /// range to modify and its new base and length, for a heap whose physical
10400 /// range(s) are set up via sysmem.
10401 ///
10402 /// Only sysmem can call this because only sysmem is handed the client end
10403 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10404 /// securemem driver is the server end of this protocol.
10405 ///
10406 /// The securemem driver must configure the range to cover only the new
10407 /// offsets before responding to this message with success.
10408 ///
10409 /// On failure, the securemem driver must ensure the range was not changed.
10410 ///
10411 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
10412 /// must not call this if !is_mod_protected_range_available.
10413 ///
10414 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10415 /// on various ranges that exist at the time of the call.
10416 ///
10417 /// The range must only be modified at one end or the other, but not both.
10418 /// If the range is getting shorter, and the un-covered blocks are not
10419 /// covered by other active ranges, any ongoing DMA to the entire range
10420 /// that's geting shorter may fail in a way that disrupts the entire system
10421 /// (bus lockup or similar), so the caller must ensure that no DMA is
10422 /// ongoing to any portion of a range that is getting shorter, unless the
10423 /// blocks being un-covered by the modification to this range are all
10424 /// covered by other active ranges, in which case no disruption to ongoing
10425 /// DMA will occur.
10426 ///
10427 /// If a range is modified to become <= zero length, the range is deleted.
10428 ///
10429 /// Errors:
10430 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10431 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
10432 /// that doesn't conform to protected_range_granularity, or old_range
10433 /// and new_range differ in both begin and end (disallowed).
10434 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10435 /// with TEE which doesn't generate zx_status_t errors).
10436 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10437 /// * other errors are possible, such as from communication failures or
10438 /// server propagation of zx_status_t failures.
10439 pub fn r#modify_secure_heap_physical_range(
10440 &self,
10441 mut range_modification: &SecureHeapAndRangeModification,
10442 ___deadline: zx::MonotonicInstant,
10443 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
10444 let _response = self.client.send_query::<
10445 SecureMemModifySecureHeapPhysicalRangeRequest,
10446 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10447 >(
10448 (range_modification,),
10449 0x154fbfa3646a890d,
10450 fidl::encoding::DynamicFlags::empty(),
10451 ___deadline,
10452 )?;
10453 Ok(_response.map(|x| x))
10454 }
10455
10456 /// Zero a sub-range of a currently-existing physical range added via
10457 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
10458 /// exactly one physical range, and must not overlap with any other
10459 /// physical range.
10460 ///
10461 /// is_covering_range_explicit - When true, the covering range must be one
10462 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
10463 /// possibly modified since. When false, the covering range must not
10464 /// be one of the ranges explicitly created via
10465 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
10466 /// a covering range not created via AddSecureHeapPhysicalRange(). The
10467 /// covering range is typically the entire physical range (or a range
10468 /// which covers even more) of a heap configured by the TEE and whose
10469 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
10470 ///
10471 /// Ongoing DMA is not disrupted by this request.
10472 pub fn r#zero_sub_range(
10473 &self,
10474 mut is_covering_range_explicit: bool,
10475 mut heap_range: &SecureHeapAndRange,
10476 ___deadline: zx::MonotonicInstant,
10477 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
10478 let _response = self.client.send_query::<
10479 SecureMemZeroSubRangeRequest,
10480 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10481 >(
10482 (is_covering_range_explicit, heap_range,),
10483 0x7480f72bb5bc7e5b,
10484 fidl::encoding::DynamicFlags::empty(),
10485 ___deadline,
10486 )?;
10487 Ok(_response.map(|x| x))
10488 }
10489}
10490
10491#[cfg(target_os = "fuchsia")]
10492impl From<SecureMemSynchronousProxy> for zx::Handle {
10493 fn from(value: SecureMemSynchronousProxy) -> Self {
10494 value.into_channel().into()
10495 }
10496}
10497
10498#[cfg(target_os = "fuchsia")]
10499impl From<fidl::Channel> for SecureMemSynchronousProxy {
10500 fn from(value: fidl::Channel) -> Self {
10501 Self::new(value)
10502 }
10503}
10504
10505#[cfg(target_os = "fuchsia")]
10506impl fidl::endpoints::FromClient for SecureMemSynchronousProxy {
10507 type Protocol = SecureMemMarker;
10508
10509 fn from_client(value: fidl::endpoints::ClientEnd<SecureMemMarker>) -> Self {
10510 Self::new(value.into_channel())
10511 }
10512}
10513
10514#[derive(Debug, Clone)]
10515pub struct SecureMemProxy {
10516 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
10517}
10518
10519impl fidl::endpoints::Proxy for SecureMemProxy {
10520 type Protocol = SecureMemMarker;
10521
10522 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
10523 Self::new(inner)
10524 }
10525
10526 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
10527 self.client.into_channel().map_err(|client| Self { client })
10528 }
10529
10530 fn as_channel(&self) -> &::fidl::AsyncChannel {
10531 self.client.as_channel()
10532 }
10533}
10534
10535impl SecureMemProxy {
10536 /// Create a new Proxy for fuchsia.sysmem/SecureMem.
10537 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
10538 let protocol_name = <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
10539 Self { client: fidl::client::Client::new(channel, protocol_name) }
10540 }
10541
10542 /// Get a Stream of events from the remote end of the protocol.
10543 ///
10544 /// # Panics
10545 ///
10546 /// Panics if the event stream was already taken.
10547 pub fn take_event_stream(&self) -> SecureMemEventStream {
10548 SecureMemEventStream { event_receiver: self.client.take_event_receiver() }
10549 }
10550
10551 /// Gets the physical address and length of any secure heap whose physical
10552 /// range is configured via the TEE.
10553 ///
10554 /// Presently, these will be fixed physical addresses and lengths, with the
10555 /// location plumbed via the TEE.
10556 ///
10557 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
10558 /// when there isn't any special heap-specific per-VMO setup or teardown
10559 /// required.
10560 ///
10561 /// The physical range must be secured/protected by the TEE before the
10562 /// securemem driver responds to this request with success.
10563 ///
10564 /// Sysmem should only call this once. Returning zero heaps is not a
10565 /// failure.
10566 ///
10567 /// Errors:
10568 /// * ZX_ERR_BAD_STATE - called more than once.
10569 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10570 /// with TEE which doesn't generate zx_status_t errors).
10571 /// * other errors are allowed; any other errors should be treated the same
10572 /// as ZX_ERR_INTERNAL.
10573 pub fn r#get_physical_secure_heaps(
10574 &self,
10575 ) -> fidl::client::QueryResponseFut<
10576 SecureMemGetPhysicalSecureHeapsResult,
10577 fidl::encoding::DefaultFuchsiaResourceDialect,
10578 > {
10579 SecureMemProxyInterface::r#get_physical_secure_heaps(self)
10580 }
10581
10582 /// This request from sysmem to the securemem driver gets the properties of
10583 /// a protected/secure heap.
10584 ///
10585 /// This only handles heaps with a single contiguous physical extent.
10586 ///
10587 /// The heap's entire physical range is indicated in case this request needs
10588 /// some physical space to auto-detect how many ranges are REE-usable. Any
10589 /// temporary HW protection ranges will be deleted before this request
10590 /// completes.
10591 pub fn r#get_physical_secure_heap_properties(
10592 &self,
10593 mut entire_heap: &SecureHeapAndRange,
10594 ) -> fidl::client::QueryResponseFut<
10595 SecureMemGetPhysicalSecureHeapPropertiesResult,
10596 fidl::encoding::DefaultFuchsiaResourceDialect,
10597 > {
10598 SecureMemProxyInterface::r#get_physical_secure_heap_properties(self, entire_heap)
10599 }
10600
10601 /// This request from sysmem to the securemem driver conveys a physical
10602 /// range to add, for a heap whose physical range(s) are set up via
10603 /// sysmem.
10604 ///
10605 /// Only sysmem can call this because only sysmem is handed the client end
10606 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10607 /// securemem driver is the server end of this protocol.
10608 ///
10609 /// The securemem driver must configure all the covered offsets as protected
10610 /// before responding to this message with success.
10611 ///
10612 /// On failure, the securemem driver must ensure the protected range was not
10613 /// created.
10614 ///
10615 /// Sysmem must only call this up to once if dynamic_protection_ranges
10616 /// false.
10617 ///
10618 /// If dynamic_protection_ranges is true, sysmem can call this multiple
10619 /// times as long as the current number of ranges never exceeds
10620 /// max_protected_range_count.
10621 ///
10622 /// The caller must not attempt to add a range that matches an
10623 /// already-existing range. Added ranges can overlap each other as long as
10624 /// no two ranges match exactly.
10625 ///
10626 /// Errors:
10627 /// * ZX_ERR_BAD_STATE - called more than once when
10628 /// !dynamic_protection_ranges. Adding a heap that would cause overall
10629 /// heap count to exceed max_protected_range_count.
10630 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10631 /// to protected_range_granularity.
10632 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10633 /// with TEE which doesn't generate zx_status_t errors).
10634 /// * other errors are possible, such as from communication failures or
10635 /// server propagation of zx_status_t failures.
10636 pub fn r#add_secure_heap_physical_range(
10637 &self,
10638 mut heap_range: &SecureHeapAndRange,
10639 ) -> fidl::client::QueryResponseFut<
10640 SecureMemAddSecureHeapPhysicalRangeResult,
10641 fidl::encoding::DefaultFuchsiaResourceDialect,
10642 > {
10643 SecureMemProxyInterface::r#add_secure_heap_physical_range(self, heap_range)
10644 }
10645
10646 /// This request from sysmem to the securemem driver conveys a physical
10647 /// range to delete, for a heap whose physical range(s) are set up via
10648 /// sysmem.
10649 ///
10650 /// Only sysmem can call this because only sysmem is handed the client end
10651 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10652 /// securemem driver is the server end of this protocol.
10653 ///
10654 /// The securemem driver must configure all the covered offsets as not
10655 /// protected before responding to this message with success.
10656 ///
10657 /// On failure, the securemem driver must ensure the protected range was not
10658 /// deleted.
10659 ///
10660 /// Sysmem must not call this if dynamic_protection_ranges false.
10661 ///
10662 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10663 /// on various ranges that exist at the time of the call.
10664 ///
10665 /// If any portion of the range being deleted is not also covered by another
10666 /// protected range, then any ongoing DMA to any part of the entire range
10667 /// may be interrupted / may fail, potentially in a way that's disruptive to
10668 /// the entire system (bus lockup or similar, depending on device details).
10669 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
10670 /// any portion of the range being deleted, unless the caller has other
10671 /// active ranges covering every block of the range being deleted. Ongoing
10672 /// DMA to/from blocks outside the range being deleted is never impacted by
10673 /// the deletion.
10674 ///
10675 /// Errors:
10676 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10677 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10678 /// to protected_range_granularity.
10679 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10680 /// with TEE which doesn't generate zx_status_t errors).
10681 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10682 /// * other errors are possible, such as from communication failures or
10683 /// server propagation of zx_status_t failures.
10684 pub fn r#delete_secure_heap_physical_range(
10685 &self,
10686 mut heap_range: &SecureHeapAndRange,
10687 ) -> fidl::client::QueryResponseFut<
10688 SecureMemDeleteSecureHeapPhysicalRangeResult,
10689 fidl::encoding::DefaultFuchsiaResourceDialect,
10690 > {
10691 SecureMemProxyInterface::r#delete_secure_heap_physical_range(self, heap_range)
10692 }
10693
10694 /// This request from sysmem to the securemem driver conveys a physical
10695 /// range to modify and its new base and length, for a heap whose physical
10696 /// range(s) are set up via sysmem.
10697 ///
10698 /// Only sysmem can call this because only sysmem is handed the client end
10699 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10700 /// securemem driver is the server end of this protocol.
10701 ///
10702 /// The securemem driver must configure the range to cover only the new
10703 /// offsets before responding to this message with success.
10704 ///
10705 /// On failure, the securemem driver must ensure the range was not changed.
10706 ///
10707 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
10708 /// must not call this if !is_mod_protected_range_available.
10709 ///
10710 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10711 /// on various ranges that exist at the time of the call.
10712 ///
10713 /// The range must only be modified at one end or the other, but not both.
10714 /// If the range is getting shorter, and the un-covered blocks are not
10715 /// covered by other active ranges, any ongoing DMA to the entire range
10716 /// that's geting shorter may fail in a way that disrupts the entire system
10717 /// (bus lockup or similar), so the caller must ensure that no DMA is
10718 /// ongoing to any portion of a range that is getting shorter, unless the
10719 /// blocks being un-covered by the modification to this range are all
10720 /// covered by other active ranges, in which case no disruption to ongoing
10721 /// DMA will occur.
10722 ///
10723 /// If a range is modified to become <= zero length, the range is deleted.
10724 ///
10725 /// Errors:
10726 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10727 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
10728 /// that doesn't conform to protected_range_granularity, or old_range
10729 /// and new_range differ in both begin and end (disallowed).
10730 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10731 /// with TEE which doesn't generate zx_status_t errors).
10732 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10733 /// * other errors are possible, such as from communication failures or
10734 /// server propagation of zx_status_t failures.
10735 pub fn r#modify_secure_heap_physical_range(
10736 &self,
10737 mut range_modification: &SecureHeapAndRangeModification,
10738 ) -> fidl::client::QueryResponseFut<
10739 SecureMemModifySecureHeapPhysicalRangeResult,
10740 fidl::encoding::DefaultFuchsiaResourceDialect,
10741 > {
10742 SecureMemProxyInterface::r#modify_secure_heap_physical_range(self, range_modification)
10743 }
10744
10745 /// Zero a sub-range of a currently-existing physical range added via
10746 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
10747 /// exactly one physical range, and must not overlap with any other
10748 /// physical range.
10749 ///
10750 /// is_covering_range_explicit - When true, the covering range must be one
10751 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
10752 /// possibly modified since. When false, the covering range must not
10753 /// be one of the ranges explicitly created via
10754 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
10755 /// a covering range not created via AddSecureHeapPhysicalRange(). The
10756 /// covering range is typically the entire physical range (or a range
10757 /// which covers even more) of a heap configured by the TEE and whose
10758 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
10759 ///
10760 /// Ongoing DMA is not disrupted by this request.
10761 pub fn r#zero_sub_range(
10762 &self,
10763 mut is_covering_range_explicit: bool,
10764 mut heap_range: &SecureHeapAndRange,
10765 ) -> fidl::client::QueryResponseFut<
10766 SecureMemZeroSubRangeResult,
10767 fidl::encoding::DefaultFuchsiaResourceDialect,
10768 > {
10769 SecureMemProxyInterface::r#zero_sub_range(self, is_covering_range_explicit, heap_range)
10770 }
10771}
10772
10773impl SecureMemProxyInterface for SecureMemProxy {
10774 type GetPhysicalSecureHeapsResponseFut = fidl::client::QueryResponseFut<
10775 SecureMemGetPhysicalSecureHeapsResult,
10776 fidl::encoding::DefaultFuchsiaResourceDialect,
10777 >;
10778 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut {
10779 fn _decode(
10780 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10781 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
10782 let _response = fidl::client::decode_transaction_body::<
10783 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapsResponse, i32>,
10784 fidl::encoding::DefaultFuchsiaResourceDialect,
10785 0x782319d6ce7fa05,
10786 >(_buf?)?;
10787 Ok(_response.map(|x| x.heaps))
10788 }
10789 self.client.send_query_and_decode::<
10790 fidl::encoding::EmptyPayload,
10791 SecureMemGetPhysicalSecureHeapsResult,
10792 >(
10793 (),
10794 0x782319d6ce7fa05,
10795 fidl::encoding::DynamicFlags::empty(),
10796 _decode,
10797 )
10798 }
10799
10800 type GetPhysicalSecureHeapPropertiesResponseFut = fidl::client::QueryResponseFut<
10801 SecureMemGetPhysicalSecureHeapPropertiesResult,
10802 fidl::encoding::DefaultFuchsiaResourceDialect,
10803 >;
10804 fn r#get_physical_secure_heap_properties(
10805 &self,
10806 mut entire_heap: &SecureHeapAndRange,
10807 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut {
10808 fn _decode(
10809 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10810 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
10811 let _response = fidl::client::decode_transaction_body::<
10812 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapPropertiesResponse, i32>,
10813 fidl::encoding::DefaultFuchsiaResourceDialect,
10814 0x26404e23f1271214,
10815 >(_buf?)?;
10816 Ok(_response.map(|x| x.properties))
10817 }
10818 self.client.send_query_and_decode::<
10819 SecureMemGetPhysicalSecureHeapPropertiesRequest,
10820 SecureMemGetPhysicalSecureHeapPropertiesResult,
10821 >(
10822 (entire_heap,),
10823 0x26404e23f1271214,
10824 fidl::encoding::DynamicFlags::empty(),
10825 _decode,
10826 )
10827 }
10828
10829 type AddSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10830 SecureMemAddSecureHeapPhysicalRangeResult,
10831 fidl::encoding::DefaultFuchsiaResourceDialect,
10832 >;
10833 fn r#add_secure_heap_physical_range(
10834 &self,
10835 mut heap_range: &SecureHeapAndRange,
10836 ) -> Self::AddSecureHeapPhysicalRangeResponseFut {
10837 fn _decode(
10838 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10839 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
10840 let _response = fidl::client::decode_transaction_body::<
10841 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10842 fidl::encoding::DefaultFuchsiaResourceDialect,
10843 0x1ca1abcee8a0b33e,
10844 >(_buf?)?;
10845 Ok(_response.map(|x| x))
10846 }
10847 self.client.send_query_and_decode::<
10848 SecureMemAddSecureHeapPhysicalRangeRequest,
10849 SecureMemAddSecureHeapPhysicalRangeResult,
10850 >(
10851 (heap_range,),
10852 0x1ca1abcee8a0b33e,
10853 fidl::encoding::DynamicFlags::empty(),
10854 _decode,
10855 )
10856 }
10857
10858 type DeleteSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10859 SecureMemDeleteSecureHeapPhysicalRangeResult,
10860 fidl::encoding::DefaultFuchsiaResourceDialect,
10861 >;
10862 fn r#delete_secure_heap_physical_range(
10863 &self,
10864 mut heap_range: &SecureHeapAndRange,
10865 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut {
10866 fn _decode(
10867 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10868 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
10869 let _response = fidl::client::decode_transaction_body::<
10870 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10871 fidl::encoding::DefaultFuchsiaResourceDialect,
10872 0x728a953e56df92ee,
10873 >(_buf?)?;
10874 Ok(_response.map(|x| x))
10875 }
10876 self.client.send_query_and_decode::<
10877 SecureMemDeleteSecureHeapPhysicalRangeRequest,
10878 SecureMemDeleteSecureHeapPhysicalRangeResult,
10879 >(
10880 (heap_range,),
10881 0x728a953e56df92ee,
10882 fidl::encoding::DynamicFlags::empty(),
10883 _decode,
10884 )
10885 }
10886
10887 type ModifySecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10888 SecureMemModifySecureHeapPhysicalRangeResult,
10889 fidl::encoding::DefaultFuchsiaResourceDialect,
10890 >;
10891 fn r#modify_secure_heap_physical_range(
10892 &self,
10893 mut range_modification: &SecureHeapAndRangeModification,
10894 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut {
10895 fn _decode(
10896 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10897 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
10898 let _response = fidl::client::decode_transaction_body::<
10899 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10900 fidl::encoding::DefaultFuchsiaResourceDialect,
10901 0x154fbfa3646a890d,
10902 >(_buf?)?;
10903 Ok(_response.map(|x| x))
10904 }
10905 self.client.send_query_and_decode::<
10906 SecureMemModifySecureHeapPhysicalRangeRequest,
10907 SecureMemModifySecureHeapPhysicalRangeResult,
10908 >(
10909 (range_modification,),
10910 0x154fbfa3646a890d,
10911 fidl::encoding::DynamicFlags::empty(),
10912 _decode,
10913 )
10914 }
10915
10916 type ZeroSubRangeResponseFut = fidl::client::QueryResponseFut<
10917 SecureMemZeroSubRangeResult,
10918 fidl::encoding::DefaultFuchsiaResourceDialect,
10919 >;
10920 fn r#zero_sub_range(
10921 &self,
10922 mut is_covering_range_explicit: bool,
10923 mut heap_range: &SecureHeapAndRange,
10924 ) -> Self::ZeroSubRangeResponseFut {
10925 fn _decode(
10926 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10927 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
10928 let _response = fidl::client::decode_transaction_body::<
10929 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10930 fidl::encoding::DefaultFuchsiaResourceDialect,
10931 0x7480f72bb5bc7e5b,
10932 >(_buf?)?;
10933 Ok(_response.map(|x| x))
10934 }
10935 self.client
10936 .send_query_and_decode::<SecureMemZeroSubRangeRequest, SecureMemZeroSubRangeResult>(
10937 (is_covering_range_explicit, heap_range),
10938 0x7480f72bb5bc7e5b,
10939 fidl::encoding::DynamicFlags::empty(),
10940 _decode,
10941 )
10942 }
10943}
10944
10945pub struct SecureMemEventStream {
10946 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
10947}
10948
10949impl std::marker::Unpin for SecureMemEventStream {}
10950
10951impl futures::stream::FusedStream for SecureMemEventStream {
10952 fn is_terminated(&self) -> bool {
10953 self.event_receiver.is_terminated()
10954 }
10955}
10956
10957impl futures::Stream for SecureMemEventStream {
10958 type Item = Result<SecureMemEvent, fidl::Error>;
10959
10960 fn poll_next(
10961 mut self: std::pin::Pin<&mut Self>,
10962 cx: &mut std::task::Context<'_>,
10963 ) -> std::task::Poll<Option<Self::Item>> {
10964 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
10965 &mut self.event_receiver,
10966 cx
10967 )?) {
10968 Some(buf) => std::task::Poll::Ready(Some(SecureMemEvent::decode(buf))),
10969 None => std::task::Poll::Ready(None),
10970 }
10971 }
10972}
10973
10974#[derive(Debug)]
10975pub enum SecureMemEvent {}
10976
10977impl SecureMemEvent {
10978 /// Decodes a message buffer as a [`SecureMemEvent`].
10979 fn decode(
10980 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
10981 ) -> Result<SecureMemEvent, fidl::Error> {
10982 let (bytes, _handles) = buf.split_mut();
10983 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
10984 debug_assert_eq!(tx_header.tx_id, 0);
10985 match tx_header.ordinal {
10986 _ => Err(fidl::Error::UnknownOrdinal {
10987 ordinal: tx_header.ordinal,
10988 protocol_name: <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
10989 }),
10990 }
10991 }
10992}
10993
10994/// A Stream of incoming requests for fuchsia.sysmem/SecureMem.
10995pub struct SecureMemRequestStream {
10996 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
10997 is_terminated: bool,
10998}
10999
11000impl std::marker::Unpin for SecureMemRequestStream {}
11001
11002impl futures::stream::FusedStream for SecureMemRequestStream {
11003 fn is_terminated(&self) -> bool {
11004 self.is_terminated
11005 }
11006}
11007
11008impl fidl::endpoints::RequestStream for SecureMemRequestStream {
11009 type Protocol = SecureMemMarker;
11010 type ControlHandle = SecureMemControlHandle;
11011
11012 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
11013 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
11014 }
11015
11016 fn control_handle(&self) -> Self::ControlHandle {
11017 SecureMemControlHandle { inner: self.inner.clone() }
11018 }
11019
11020 fn into_inner(
11021 self,
11022 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
11023 {
11024 (self.inner, self.is_terminated)
11025 }
11026
11027 fn from_inner(
11028 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11029 is_terminated: bool,
11030 ) -> Self {
11031 Self { inner, is_terminated }
11032 }
11033}
11034
11035impl futures::Stream for SecureMemRequestStream {
11036 type Item = Result<SecureMemRequest, fidl::Error>;
11037
11038 fn poll_next(
11039 mut self: std::pin::Pin<&mut Self>,
11040 cx: &mut std::task::Context<'_>,
11041 ) -> std::task::Poll<Option<Self::Item>> {
11042 let this = &mut *self;
11043 if this.inner.check_shutdown(cx) {
11044 this.is_terminated = true;
11045 return std::task::Poll::Ready(None);
11046 }
11047 if this.is_terminated {
11048 panic!("polled SecureMemRequestStream after completion");
11049 }
11050 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
11051 |bytes, handles| {
11052 match this.inner.channel().read_etc(cx, bytes, handles) {
11053 std::task::Poll::Ready(Ok(())) => {}
11054 std::task::Poll::Pending => return std::task::Poll::Pending,
11055 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
11056 this.is_terminated = true;
11057 return std::task::Poll::Ready(None);
11058 }
11059 std::task::Poll::Ready(Err(e)) => {
11060 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
11061 e.into(),
11062 ))));
11063 }
11064 }
11065
11066 // A message has been received from the channel
11067 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
11068
11069 std::task::Poll::Ready(Some(match header.ordinal {
11070 0x782319d6ce7fa05 => {
11071 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11072 let mut req = fidl::new_empty!(
11073 fidl::encoding::EmptyPayload,
11074 fidl::encoding::DefaultFuchsiaResourceDialect
11075 );
11076 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11077 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11078 Ok(SecureMemRequest::GetPhysicalSecureHeaps {
11079 responder: SecureMemGetPhysicalSecureHeapsResponder {
11080 control_handle: std::mem::ManuallyDrop::new(control_handle),
11081 tx_id: header.tx_id,
11082 },
11083 })
11084 }
11085 0x26404e23f1271214 => {
11086 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11087 let mut req = fidl::new_empty!(
11088 SecureMemGetPhysicalSecureHeapPropertiesRequest,
11089 fidl::encoding::DefaultFuchsiaResourceDialect
11090 );
11091 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemGetPhysicalSecureHeapPropertiesRequest>(&header, _body_bytes, handles, &mut req)?;
11092 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11093 Ok(SecureMemRequest::GetPhysicalSecureHeapProperties {
11094 entire_heap: req.entire_heap,
11095
11096 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder {
11097 control_handle: std::mem::ManuallyDrop::new(control_handle),
11098 tx_id: header.tx_id,
11099 },
11100 })
11101 }
11102 0x1ca1abcee8a0b33e => {
11103 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11104 let mut req = fidl::new_empty!(
11105 SecureMemAddSecureHeapPhysicalRangeRequest,
11106 fidl::encoding::DefaultFuchsiaResourceDialect
11107 );
11108 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemAddSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11109 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11110 Ok(SecureMemRequest::AddSecureHeapPhysicalRange {
11111 heap_range: req.heap_range,
11112
11113 responder: SecureMemAddSecureHeapPhysicalRangeResponder {
11114 control_handle: std::mem::ManuallyDrop::new(control_handle),
11115 tx_id: header.tx_id,
11116 },
11117 })
11118 }
11119 0x728a953e56df92ee => {
11120 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11121 let mut req = fidl::new_empty!(
11122 SecureMemDeleteSecureHeapPhysicalRangeRequest,
11123 fidl::encoding::DefaultFuchsiaResourceDialect
11124 );
11125 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemDeleteSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11126 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11127 Ok(SecureMemRequest::DeleteSecureHeapPhysicalRange {
11128 heap_range: req.heap_range,
11129
11130 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder {
11131 control_handle: std::mem::ManuallyDrop::new(control_handle),
11132 tx_id: header.tx_id,
11133 },
11134 })
11135 }
11136 0x154fbfa3646a890d => {
11137 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11138 let mut req = fidl::new_empty!(
11139 SecureMemModifySecureHeapPhysicalRangeRequest,
11140 fidl::encoding::DefaultFuchsiaResourceDialect
11141 );
11142 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemModifySecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11143 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11144 Ok(SecureMemRequest::ModifySecureHeapPhysicalRange {
11145 range_modification: req.range_modification,
11146
11147 responder: SecureMemModifySecureHeapPhysicalRangeResponder {
11148 control_handle: std::mem::ManuallyDrop::new(control_handle),
11149 tx_id: header.tx_id,
11150 },
11151 })
11152 }
11153 0x7480f72bb5bc7e5b => {
11154 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11155 let mut req = fidl::new_empty!(
11156 SecureMemZeroSubRangeRequest,
11157 fidl::encoding::DefaultFuchsiaResourceDialect
11158 );
11159 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemZeroSubRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11160 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11161 Ok(SecureMemRequest::ZeroSubRange {
11162 is_covering_range_explicit: req.is_covering_range_explicit,
11163 heap_range: req.heap_range,
11164
11165 responder: SecureMemZeroSubRangeResponder {
11166 control_handle: std::mem::ManuallyDrop::new(control_handle),
11167 tx_id: header.tx_id,
11168 },
11169 })
11170 }
11171 _ => Err(fidl::Error::UnknownOrdinal {
11172 ordinal: header.ordinal,
11173 protocol_name:
11174 <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
11175 }),
11176 }))
11177 },
11178 )
11179 }
11180}
11181
11182/// SecureMem
11183///
11184/// The client is sysmem. The server is securemem driver.
11185///
11186/// TEE - Trusted Execution Environment.
11187///
11188/// REE - Rich Execution Environment.
11189///
11190/// Enables sysmem to call the securemem driver to get any secure heaps
11191/// configured via the TEE (or via the securemem driver), and set any physical
11192/// secure heaps configured via sysmem.
11193///
11194/// Presently, dynamically-allocated secure heaps are configured via sysmem, as
11195/// it starts quite early during boot and can successfully reserve contiguous
11196/// physical memory. Presently, fixed-location secure heaps are configured via
11197/// TEE, as the plumbing goes from the bootloader to the TEE. However, this
11198/// protocol intentionally doesn't care which heaps are dynamically-allocated
11199/// and which are fixed-location.
11200#[derive(Debug)]
11201pub enum SecureMemRequest {
11202 /// Gets the physical address and length of any secure heap whose physical
11203 /// range is configured via the TEE.
11204 ///
11205 /// Presently, these will be fixed physical addresses and lengths, with the
11206 /// location plumbed via the TEE.
11207 ///
11208 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
11209 /// when there isn't any special heap-specific per-VMO setup or teardown
11210 /// required.
11211 ///
11212 /// The physical range must be secured/protected by the TEE before the
11213 /// securemem driver responds to this request with success.
11214 ///
11215 /// Sysmem should only call this once. Returning zero heaps is not a
11216 /// failure.
11217 ///
11218 /// Errors:
11219 /// * ZX_ERR_BAD_STATE - called more than once.
11220 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11221 /// with TEE which doesn't generate zx_status_t errors).
11222 /// * other errors are allowed; any other errors should be treated the same
11223 /// as ZX_ERR_INTERNAL.
11224 GetPhysicalSecureHeaps { responder: SecureMemGetPhysicalSecureHeapsResponder },
11225 /// This request from sysmem to the securemem driver gets the properties of
11226 /// a protected/secure heap.
11227 ///
11228 /// This only handles heaps with a single contiguous physical extent.
11229 ///
11230 /// The heap's entire physical range is indicated in case this request needs
11231 /// some physical space to auto-detect how many ranges are REE-usable. Any
11232 /// temporary HW protection ranges will be deleted before this request
11233 /// completes.
11234 GetPhysicalSecureHeapProperties {
11235 entire_heap: SecureHeapAndRange,
11236 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder,
11237 },
11238 /// This request from sysmem to the securemem driver conveys a physical
11239 /// range to add, for a heap whose physical range(s) are set up via
11240 /// sysmem.
11241 ///
11242 /// Only sysmem can call this because only sysmem is handed the client end
11243 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11244 /// securemem driver is the server end of this protocol.
11245 ///
11246 /// The securemem driver must configure all the covered offsets as protected
11247 /// before responding to this message with success.
11248 ///
11249 /// On failure, the securemem driver must ensure the protected range was not
11250 /// created.
11251 ///
11252 /// Sysmem must only call this up to once if dynamic_protection_ranges
11253 /// false.
11254 ///
11255 /// If dynamic_protection_ranges is true, sysmem can call this multiple
11256 /// times as long as the current number of ranges never exceeds
11257 /// max_protected_range_count.
11258 ///
11259 /// The caller must not attempt to add a range that matches an
11260 /// already-existing range. Added ranges can overlap each other as long as
11261 /// no two ranges match exactly.
11262 ///
11263 /// Errors:
11264 /// * ZX_ERR_BAD_STATE - called more than once when
11265 /// !dynamic_protection_ranges. Adding a heap that would cause overall
11266 /// heap count to exceed max_protected_range_count.
11267 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
11268 /// to protected_range_granularity.
11269 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11270 /// with TEE which doesn't generate zx_status_t errors).
11271 /// * other errors are possible, such as from communication failures or
11272 /// server propagation of zx_status_t failures.
11273 AddSecureHeapPhysicalRange {
11274 heap_range: SecureHeapAndRange,
11275 responder: SecureMemAddSecureHeapPhysicalRangeResponder,
11276 },
11277 /// This request from sysmem to the securemem driver conveys a physical
11278 /// range to delete, for a heap whose physical range(s) are set up via
11279 /// sysmem.
11280 ///
11281 /// Only sysmem can call this because only sysmem is handed the client end
11282 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11283 /// securemem driver is the server end of this protocol.
11284 ///
11285 /// The securemem driver must configure all the covered offsets as not
11286 /// protected before responding to this message with success.
11287 ///
11288 /// On failure, the securemem driver must ensure the protected range was not
11289 /// deleted.
11290 ///
11291 /// Sysmem must not call this if dynamic_protection_ranges false.
11292 ///
11293 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
11294 /// on various ranges that exist at the time of the call.
11295 ///
11296 /// If any portion of the range being deleted is not also covered by another
11297 /// protected range, then any ongoing DMA to any part of the entire range
11298 /// may be interrupted / may fail, potentially in a way that's disruptive to
11299 /// the entire system (bus lockup or similar, depending on device details).
11300 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
11301 /// any portion of the range being deleted, unless the caller has other
11302 /// active ranges covering every block of the range being deleted. Ongoing
11303 /// DMA to/from blocks outside the range being deleted is never impacted by
11304 /// the deletion.
11305 ///
11306 /// Errors:
11307 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
11308 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
11309 /// to protected_range_granularity.
11310 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11311 /// with TEE which doesn't generate zx_status_t errors).
11312 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
11313 /// * other errors are possible, such as from communication failures or
11314 /// server propagation of zx_status_t failures.
11315 DeleteSecureHeapPhysicalRange {
11316 heap_range: SecureHeapAndRange,
11317 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder,
11318 },
11319 /// This request from sysmem to the securemem driver conveys a physical
11320 /// range to modify and its new base and length, for a heap whose physical
11321 /// range(s) are set up via sysmem.
11322 ///
11323 /// Only sysmem can call this because only sysmem is handed the client end
11324 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11325 /// securemem driver is the server end of this protocol.
11326 ///
11327 /// The securemem driver must configure the range to cover only the new
11328 /// offsets before responding to this message with success.
11329 ///
11330 /// On failure, the securemem driver must ensure the range was not changed.
11331 ///
11332 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
11333 /// must not call this if !is_mod_protected_range_available.
11334 ///
11335 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
11336 /// on various ranges that exist at the time of the call.
11337 ///
11338 /// The range must only be modified at one end or the other, but not both.
11339 /// If the range is getting shorter, and the un-covered blocks are not
11340 /// covered by other active ranges, any ongoing DMA to the entire range
11341 /// that's geting shorter may fail in a way that disrupts the entire system
11342 /// (bus lockup or similar), so the caller must ensure that no DMA is
11343 /// ongoing to any portion of a range that is getting shorter, unless the
11344 /// blocks being un-covered by the modification to this range are all
11345 /// covered by other active ranges, in which case no disruption to ongoing
11346 /// DMA will occur.
11347 ///
11348 /// If a range is modified to become <= zero length, the range is deleted.
11349 ///
11350 /// Errors:
11351 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
11352 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
11353 /// that doesn't conform to protected_range_granularity, or old_range
11354 /// and new_range differ in both begin and end (disallowed).
11355 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11356 /// with TEE which doesn't generate zx_status_t errors).
11357 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
11358 /// * other errors are possible, such as from communication failures or
11359 /// server propagation of zx_status_t failures.
11360 ModifySecureHeapPhysicalRange {
11361 range_modification: SecureHeapAndRangeModification,
11362 responder: SecureMemModifySecureHeapPhysicalRangeResponder,
11363 },
11364 /// Zero a sub-range of a currently-existing physical range added via
11365 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
11366 /// exactly one physical range, and must not overlap with any other
11367 /// physical range.
11368 ///
11369 /// is_covering_range_explicit - When true, the covering range must be one
11370 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
11371 /// possibly modified since. When false, the covering range must not
11372 /// be one of the ranges explicitly created via
11373 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
11374 /// a covering range not created via AddSecureHeapPhysicalRange(). The
11375 /// covering range is typically the entire physical range (or a range
11376 /// which covers even more) of a heap configured by the TEE and whose
11377 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
11378 ///
11379 /// Ongoing DMA is not disrupted by this request.
11380 ZeroSubRange {
11381 is_covering_range_explicit: bool,
11382 heap_range: SecureHeapAndRange,
11383 responder: SecureMemZeroSubRangeResponder,
11384 },
11385}
11386
11387impl SecureMemRequest {
11388 #[allow(irrefutable_let_patterns)]
11389 pub fn into_get_physical_secure_heaps(
11390 self,
11391 ) -> Option<(SecureMemGetPhysicalSecureHeapsResponder)> {
11392 if let SecureMemRequest::GetPhysicalSecureHeaps { responder } = self {
11393 Some((responder))
11394 } else {
11395 None
11396 }
11397 }
11398
11399 #[allow(irrefutable_let_patterns)]
11400 pub fn into_get_physical_secure_heap_properties(
11401 self,
11402 ) -> Option<(SecureHeapAndRange, SecureMemGetPhysicalSecureHeapPropertiesResponder)> {
11403 if let SecureMemRequest::GetPhysicalSecureHeapProperties { entire_heap, responder } = self {
11404 Some((entire_heap, responder))
11405 } else {
11406 None
11407 }
11408 }
11409
11410 #[allow(irrefutable_let_patterns)]
11411 pub fn into_add_secure_heap_physical_range(
11412 self,
11413 ) -> Option<(SecureHeapAndRange, SecureMemAddSecureHeapPhysicalRangeResponder)> {
11414 if let SecureMemRequest::AddSecureHeapPhysicalRange { heap_range, responder } = self {
11415 Some((heap_range, responder))
11416 } else {
11417 None
11418 }
11419 }
11420
11421 #[allow(irrefutable_let_patterns)]
11422 pub fn into_delete_secure_heap_physical_range(
11423 self,
11424 ) -> Option<(SecureHeapAndRange, SecureMemDeleteSecureHeapPhysicalRangeResponder)> {
11425 if let SecureMemRequest::DeleteSecureHeapPhysicalRange { heap_range, responder } = self {
11426 Some((heap_range, responder))
11427 } else {
11428 None
11429 }
11430 }
11431
11432 #[allow(irrefutable_let_patterns)]
11433 pub fn into_modify_secure_heap_physical_range(
11434 self,
11435 ) -> Option<(SecureHeapAndRangeModification, SecureMemModifySecureHeapPhysicalRangeResponder)>
11436 {
11437 if let SecureMemRequest::ModifySecureHeapPhysicalRange { range_modification, responder } =
11438 self
11439 {
11440 Some((range_modification, responder))
11441 } else {
11442 None
11443 }
11444 }
11445
11446 #[allow(irrefutable_let_patterns)]
11447 pub fn into_zero_sub_range(
11448 self,
11449 ) -> Option<(bool, SecureHeapAndRange, SecureMemZeroSubRangeResponder)> {
11450 if let SecureMemRequest::ZeroSubRange {
11451 is_covering_range_explicit,
11452 heap_range,
11453 responder,
11454 } = self
11455 {
11456 Some((is_covering_range_explicit, heap_range, responder))
11457 } else {
11458 None
11459 }
11460 }
11461
11462 /// Name of the method defined in FIDL
11463 pub fn method_name(&self) -> &'static str {
11464 match *self {
11465 SecureMemRequest::GetPhysicalSecureHeaps { .. } => "get_physical_secure_heaps",
11466 SecureMemRequest::GetPhysicalSecureHeapProperties { .. } => {
11467 "get_physical_secure_heap_properties"
11468 }
11469 SecureMemRequest::AddSecureHeapPhysicalRange { .. } => "add_secure_heap_physical_range",
11470 SecureMemRequest::DeleteSecureHeapPhysicalRange { .. } => {
11471 "delete_secure_heap_physical_range"
11472 }
11473 SecureMemRequest::ModifySecureHeapPhysicalRange { .. } => {
11474 "modify_secure_heap_physical_range"
11475 }
11476 SecureMemRequest::ZeroSubRange { .. } => "zero_sub_range",
11477 }
11478 }
11479}
11480
11481#[derive(Debug, Clone)]
11482pub struct SecureMemControlHandle {
11483 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11484}
11485
11486impl fidl::endpoints::ControlHandle for SecureMemControlHandle {
11487 fn shutdown(&self) {
11488 self.inner.shutdown()
11489 }
11490 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
11491 self.inner.shutdown_with_epitaph(status)
11492 }
11493
11494 fn is_closed(&self) -> bool {
11495 self.inner.channel().is_closed()
11496 }
11497 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
11498 self.inner.channel().on_closed()
11499 }
11500
11501 #[cfg(target_os = "fuchsia")]
11502 fn signal_peer(
11503 &self,
11504 clear_mask: zx::Signals,
11505 set_mask: zx::Signals,
11506 ) -> Result<(), zx_status::Status> {
11507 use fidl::Peered;
11508 self.inner.channel().signal_peer(clear_mask, set_mask)
11509 }
11510}
11511
11512impl SecureMemControlHandle {}
11513
11514#[must_use = "FIDL methods require a response to be sent"]
11515#[derive(Debug)]
11516pub struct SecureMemGetPhysicalSecureHeapsResponder {
11517 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11518 tx_id: u32,
11519}
11520
11521/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11522/// if the responder is dropped without sending a response, so that the client
11523/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11524impl std::ops::Drop for SecureMemGetPhysicalSecureHeapsResponder {
11525 fn drop(&mut self) {
11526 self.control_handle.shutdown();
11527 // Safety: drops once, never accessed again
11528 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11529 }
11530}
11531
11532impl fidl::endpoints::Responder for SecureMemGetPhysicalSecureHeapsResponder {
11533 type ControlHandle = SecureMemControlHandle;
11534
11535 fn control_handle(&self) -> &SecureMemControlHandle {
11536 &self.control_handle
11537 }
11538
11539 fn drop_without_shutdown(mut self) {
11540 // Safety: drops once, never accessed again due to mem::forget
11541 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11542 // Prevent Drop from running (which would shut down the channel)
11543 std::mem::forget(self);
11544 }
11545}
11546
11547impl SecureMemGetPhysicalSecureHeapsResponder {
11548 /// Sends a response to the FIDL transaction.
11549 ///
11550 /// Sets the channel to shutdown if an error occurs.
11551 pub fn send(self, mut result: Result<&SecureHeapsAndRanges, i32>) -> Result<(), fidl::Error> {
11552 let _result = self.send_raw(result);
11553 if _result.is_err() {
11554 self.control_handle.shutdown();
11555 }
11556 self.drop_without_shutdown();
11557 _result
11558 }
11559
11560 /// Similar to "send" but does not shutdown the channel if an error occurs.
11561 pub fn send_no_shutdown_on_err(
11562 self,
11563 mut result: Result<&SecureHeapsAndRanges, i32>,
11564 ) -> Result<(), fidl::Error> {
11565 let _result = self.send_raw(result);
11566 self.drop_without_shutdown();
11567 _result
11568 }
11569
11570 fn send_raw(&self, mut result: Result<&SecureHeapsAndRanges, i32>) -> Result<(), fidl::Error> {
11571 self.control_handle.inner.send::<fidl::encoding::ResultType<
11572 SecureMemGetPhysicalSecureHeapsResponse,
11573 i32,
11574 >>(
11575 result.map(|heaps| (heaps,)),
11576 self.tx_id,
11577 0x782319d6ce7fa05,
11578 fidl::encoding::DynamicFlags::empty(),
11579 )
11580 }
11581}
11582
11583#[must_use = "FIDL methods require a response to be sent"]
11584#[derive(Debug)]
11585pub struct SecureMemGetPhysicalSecureHeapPropertiesResponder {
11586 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11587 tx_id: u32,
11588}
11589
11590/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11591/// if the responder is dropped without sending a response, so that the client
11592/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11593impl std::ops::Drop for SecureMemGetPhysicalSecureHeapPropertiesResponder {
11594 fn drop(&mut self) {
11595 self.control_handle.shutdown();
11596 // Safety: drops once, never accessed again
11597 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11598 }
11599}
11600
11601impl fidl::endpoints::Responder for SecureMemGetPhysicalSecureHeapPropertiesResponder {
11602 type ControlHandle = SecureMemControlHandle;
11603
11604 fn control_handle(&self) -> &SecureMemControlHandle {
11605 &self.control_handle
11606 }
11607
11608 fn drop_without_shutdown(mut self) {
11609 // Safety: drops once, never accessed again due to mem::forget
11610 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11611 // Prevent Drop from running (which would shut down the channel)
11612 std::mem::forget(self);
11613 }
11614}
11615
11616impl SecureMemGetPhysicalSecureHeapPropertiesResponder {
11617 /// Sends a response to the FIDL transaction.
11618 ///
11619 /// Sets the channel to shutdown if an error occurs.
11620 pub fn send(self, mut result: Result<&SecureHeapProperties, i32>) -> Result<(), fidl::Error> {
11621 let _result = self.send_raw(result);
11622 if _result.is_err() {
11623 self.control_handle.shutdown();
11624 }
11625 self.drop_without_shutdown();
11626 _result
11627 }
11628
11629 /// Similar to "send" but does not shutdown the channel if an error occurs.
11630 pub fn send_no_shutdown_on_err(
11631 self,
11632 mut result: Result<&SecureHeapProperties, i32>,
11633 ) -> Result<(), fidl::Error> {
11634 let _result = self.send_raw(result);
11635 self.drop_without_shutdown();
11636 _result
11637 }
11638
11639 fn send_raw(&self, mut result: Result<&SecureHeapProperties, i32>) -> Result<(), fidl::Error> {
11640 self.control_handle.inner.send::<fidl::encoding::ResultType<
11641 SecureMemGetPhysicalSecureHeapPropertiesResponse,
11642 i32,
11643 >>(
11644 result.map(|properties| (properties,)),
11645 self.tx_id,
11646 0x26404e23f1271214,
11647 fidl::encoding::DynamicFlags::empty(),
11648 )
11649 }
11650}
11651
11652#[must_use = "FIDL methods require a response to be sent"]
11653#[derive(Debug)]
11654pub struct SecureMemAddSecureHeapPhysicalRangeResponder {
11655 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11656 tx_id: u32,
11657}
11658
11659/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11660/// if the responder is dropped without sending a response, so that the client
11661/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11662impl std::ops::Drop for SecureMemAddSecureHeapPhysicalRangeResponder {
11663 fn drop(&mut self) {
11664 self.control_handle.shutdown();
11665 // Safety: drops once, never accessed again
11666 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11667 }
11668}
11669
11670impl fidl::endpoints::Responder for SecureMemAddSecureHeapPhysicalRangeResponder {
11671 type ControlHandle = SecureMemControlHandle;
11672
11673 fn control_handle(&self) -> &SecureMemControlHandle {
11674 &self.control_handle
11675 }
11676
11677 fn drop_without_shutdown(mut self) {
11678 // Safety: drops once, never accessed again due to mem::forget
11679 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11680 // Prevent Drop from running (which would shut down the channel)
11681 std::mem::forget(self);
11682 }
11683}
11684
11685impl SecureMemAddSecureHeapPhysicalRangeResponder {
11686 /// Sends a response to the FIDL transaction.
11687 ///
11688 /// Sets the channel to shutdown if an error occurs.
11689 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11690 let _result = self.send_raw(result);
11691 if _result.is_err() {
11692 self.control_handle.shutdown();
11693 }
11694 self.drop_without_shutdown();
11695 _result
11696 }
11697
11698 /// Similar to "send" but does not shutdown the channel if an error occurs.
11699 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11700 let _result = self.send_raw(result);
11701 self.drop_without_shutdown();
11702 _result
11703 }
11704
11705 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11706 self.control_handle
11707 .inner
11708 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11709 result,
11710 self.tx_id,
11711 0x1ca1abcee8a0b33e,
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 SecureMemDeleteSecureHeapPhysicalRangeResponder {
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 SecureMemDeleteSecureHeapPhysicalRangeResponder {
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 SecureMemDeleteSecureHeapPhysicalRangeResponder {
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 SecureMemDeleteSecureHeapPhysicalRangeResponder {
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<(), 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(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11765 let _result = self.send_raw(result);
11766 self.drop_without_shutdown();
11767 _result
11768 }
11769
11770 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11771 self.control_handle
11772 .inner
11773 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11774 result,
11775 self.tx_id,
11776 0x728a953e56df92ee,
11777 fidl::encoding::DynamicFlags::empty(),
11778 )
11779 }
11780}
11781
11782#[must_use = "FIDL methods require a response to be sent"]
11783#[derive(Debug)]
11784pub struct SecureMemModifySecureHeapPhysicalRangeResponder {
11785 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11786 tx_id: u32,
11787}
11788
11789/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11790/// if the responder is dropped without sending a response, so that the client
11791/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11792impl std::ops::Drop for SecureMemModifySecureHeapPhysicalRangeResponder {
11793 fn drop(&mut self) {
11794 self.control_handle.shutdown();
11795 // Safety: drops once, never accessed again
11796 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11797 }
11798}
11799
11800impl fidl::endpoints::Responder for SecureMemModifySecureHeapPhysicalRangeResponder {
11801 type ControlHandle = SecureMemControlHandle;
11802
11803 fn control_handle(&self) -> &SecureMemControlHandle {
11804 &self.control_handle
11805 }
11806
11807 fn drop_without_shutdown(mut self) {
11808 // Safety: drops once, never accessed again due to mem::forget
11809 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11810 // Prevent Drop from running (which would shut down the channel)
11811 std::mem::forget(self);
11812 }
11813}
11814
11815impl SecureMemModifySecureHeapPhysicalRangeResponder {
11816 /// Sends a response to the FIDL transaction.
11817 ///
11818 /// Sets the channel to shutdown if an error occurs.
11819 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11820 let _result = self.send_raw(result);
11821 if _result.is_err() {
11822 self.control_handle.shutdown();
11823 }
11824 self.drop_without_shutdown();
11825 _result
11826 }
11827
11828 /// Similar to "send" but does not shutdown the channel if an error occurs.
11829 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11830 let _result = self.send_raw(result);
11831 self.drop_without_shutdown();
11832 _result
11833 }
11834
11835 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11836 self.control_handle
11837 .inner
11838 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11839 result,
11840 self.tx_id,
11841 0x154fbfa3646a890d,
11842 fidl::encoding::DynamicFlags::empty(),
11843 )
11844 }
11845}
11846
11847#[must_use = "FIDL methods require a response to be sent"]
11848#[derive(Debug)]
11849pub struct SecureMemZeroSubRangeResponder {
11850 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11851 tx_id: u32,
11852}
11853
11854/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11855/// if the responder is dropped without sending a response, so that the client
11856/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11857impl std::ops::Drop for SecureMemZeroSubRangeResponder {
11858 fn drop(&mut self) {
11859 self.control_handle.shutdown();
11860 // Safety: drops once, never accessed again
11861 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11862 }
11863}
11864
11865impl fidl::endpoints::Responder for SecureMemZeroSubRangeResponder {
11866 type ControlHandle = SecureMemControlHandle;
11867
11868 fn control_handle(&self) -> &SecureMemControlHandle {
11869 &self.control_handle
11870 }
11871
11872 fn drop_without_shutdown(mut self) {
11873 // Safety: drops once, never accessed again due to mem::forget
11874 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11875 // Prevent Drop from running (which would shut down the channel)
11876 std::mem::forget(self);
11877 }
11878}
11879
11880impl SecureMemZeroSubRangeResponder {
11881 /// Sends a response to the FIDL transaction.
11882 ///
11883 /// Sets the channel to shutdown if an error occurs.
11884 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11885 let _result = self.send_raw(result);
11886 if _result.is_err() {
11887 self.control_handle.shutdown();
11888 }
11889 self.drop_without_shutdown();
11890 _result
11891 }
11892
11893 /// Similar to "send" but does not shutdown the channel if an error occurs.
11894 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11895 let _result = self.send_raw(result);
11896 self.drop_without_shutdown();
11897 _result
11898 }
11899
11900 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11901 self.control_handle
11902 .inner
11903 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11904 result,
11905 self.tx_id,
11906 0x7480f72bb5bc7e5b,
11907 fidl::encoding::DynamicFlags::empty(),
11908 )
11909 }
11910}
11911
11912mod internal {
11913 use super::*;
11914
11915 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateNonSharedCollectionRequest {
11916 type Borrowed<'a> = &'a mut Self;
11917 fn take_or_borrow<'a>(
11918 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
11919 ) -> Self::Borrowed<'a> {
11920 value
11921 }
11922 }
11923
11924 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateNonSharedCollectionRequest {
11925 type Owned = Self;
11926
11927 #[inline(always)]
11928 fn inline_align(_context: fidl::encoding::Context) -> usize {
11929 4
11930 }
11931
11932 #[inline(always)]
11933 fn inline_size(_context: fidl::encoding::Context) -> usize {
11934 4
11935 }
11936 }
11937
11938 unsafe impl
11939 fidl::encoding::Encode<
11940 AllocatorAllocateNonSharedCollectionRequest,
11941 fidl::encoding::DefaultFuchsiaResourceDialect,
11942 > for &mut AllocatorAllocateNonSharedCollectionRequest
11943 {
11944 #[inline]
11945 unsafe fn encode(
11946 self,
11947 encoder: &mut fidl::encoding::Encoder<
11948 '_,
11949 fidl::encoding::DefaultFuchsiaResourceDialect,
11950 >,
11951 offset: usize,
11952 _depth: fidl::encoding::Depth,
11953 ) -> fidl::Result<()> {
11954 encoder.debug_check_bounds::<AllocatorAllocateNonSharedCollectionRequest>(offset);
11955 // Delegate to tuple encoding.
11956 fidl::encoding::Encode::<AllocatorAllocateNonSharedCollectionRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
11957 (
11958 <fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.collection_request),
11959 ),
11960 encoder, offset, _depth
11961 )
11962 }
11963 }
11964 unsafe impl<
11965 T0: fidl::encoding::Encode<
11966 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
11967 fidl::encoding::DefaultFuchsiaResourceDialect,
11968 >,
11969 >
11970 fidl::encoding::Encode<
11971 AllocatorAllocateNonSharedCollectionRequest,
11972 fidl::encoding::DefaultFuchsiaResourceDialect,
11973 > for (T0,)
11974 {
11975 #[inline]
11976 unsafe fn encode(
11977 self,
11978 encoder: &mut fidl::encoding::Encoder<
11979 '_,
11980 fidl::encoding::DefaultFuchsiaResourceDialect,
11981 >,
11982 offset: usize,
11983 depth: fidl::encoding::Depth,
11984 ) -> fidl::Result<()> {
11985 encoder.debug_check_bounds::<AllocatorAllocateNonSharedCollectionRequest>(offset);
11986 // Zero out padding regions. There's no need to apply masks
11987 // because the unmasked parts will be overwritten by fields.
11988 // Write the fields.
11989 self.0.encode(encoder, offset + 0, depth)?;
11990 Ok(())
11991 }
11992 }
11993
11994 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
11995 for AllocatorAllocateNonSharedCollectionRequest
11996 {
11997 #[inline(always)]
11998 fn new_empty() -> Self {
11999 Self {
12000 collection_request: fidl::new_empty!(
12001 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12002 fidl::encoding::DefaultFuchsiaResourceDialect
12003 ),
12004 }
12005 }
12006
12007 #[inline]
12008 unsafe fn decode(
12009 &mut self,
12010 decoder: &mut fidl::encoding::Decoder<
12011 '_,
12012 fidl::encoding::DefaultFuchsiaResourceDialect,
12013 >,
12014 offset: usize,
12015 _depth: fidl::encoding::Depth,
12016 ) -> fidl::Result<()> {
12017 decoder.debug_check_bounds::<Self>(offset);
12018 // Verify that padding bytes are zero.
12019 fidl::decode!(
12020 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12021 fidl::encoding::DefaultFuchsiaResourceDialect,
12022 &mut self.collection_request,
12023 decoder,
12024 offset + 0,
12025 _depth
12026 )?;
12027 Ok(())
12028 }
12029 }
12030
12031 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateSharedCollectionRequest {
12032 type Borrowed<'a> = &'a mut Self;
12033 fn take_or_borrow<'a>(
12034 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12035 ) -> Self::Borrowed<'a> {
12036 value
12037 }
12038 }
12039
12040 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateSharedCollectionRequest {
12041 type Owned = Self;
12042
12043 #[inline(always)]
12044 fn inline_align(_context: fidl::encoding::Context) -> usize {
12045 4
12046 }
12047
12048 #[inline(always)]
12049 fn inline_size(_context: fidl::encoding::Context) -> usize {
12050 4
12051 }
12052 }
12053
12054 unsafe impl
12055 fidl::encoding::Encode<
12056 AllocatorAllocateSharedCollectionRequest,
12057 fidl::encoding::DefaultFuchsiaResourceDialect,
12058 > for &mut AllocatorAllocateSharedCollectionRequest
12059 {
12060 #[inline]
12061 unsafe fn encode(
12062 self,
12063 encoder: &mut fidl::encoding::Encoder<
12064 '_,
12065 fidl::encoding::DefaultFuchsiaResourceDialect,
12066 >,
12067 offset: usize,
12068 _depth: fidl::encoding::Depth,
12069 ) -> fidl::Result<()> {
12070 encoder.debug_check_bounds::<AllocatorAllocateSharedCollectionRequest>(offset);
12071 // Delegate to tuple encoding.
12072 fidl::encoding::Encode::<
12073 AllocatorAllocateSharedCollectionRequest,
12074 fidl::encoding::DefaultFuchsiaResourceDialect,
12075 >::encode(
12076 (
12077 <fidl::encoding::Endpoint<
12078 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12079 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12080 &mut self.token_request,
12081 ),
12082 ),
12083 encoder,
12084 offset,
12085 _depth,
12086 )
12087 }
12088 }
12089 unsafe impl<
12090 T0: fidl::encoding::Encode<
12091 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12092 fidl::encoding::DefaultFuchsiaResourceDialect,
12093 >,
12094 >
12095 fidl::encoding::Encode<
12096 AllocatorAllocateSharedCollectionRequest,
12097 fidl::encoding::DefaultFuchsiaResourceDialect,
12098 > for (T0,)
12099 {
12100 #[inline]
12101 unsafe fn encode(
12102 self,
12103 encoder: &mut fidl::encoding::Encoder<
12104 '_,
12105 fidl::encoding::DefaultFuchsiaResourceDialect,
12106 >,
12107 offset: usize,
12108 depth: fidl::encoding::Depth,
12109 ) -> fidl::Result<()> {
12110 encoder.debug_check_bounds::<AllocatorAllocateSharedCollectionRequest>(offset);
12111 // Zero out padding regions. There's no need to apply masks
12112 // because the unmasked parts will be overwritten by fields.
12113 // Write the fields.
12114 self.0.encode(encoder, offset + 0, depth)?;
12115 Ok(())
12116 }
12117 }
12118
12119 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12120 for AllocatorAllocateSharedCollectionRequest
12121 {
12122 #[inline(always)]
12123 fn new_empty() -> Self {
12124 Self {
12125 token_request: fidl::new_empty!(
12126 fidl::encoding::Endpoint<
12127 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12128 >,
12129 fidl::encoding::DefaultFuchsiaResourceDialect
12130 ),
12131 }
12132 }
12133
12134 #[inline]
12135 unsafe fn decode(
12136 &mut self,
12137 decoder: &mut fidl::encoding::Decoder<
12138 '_,
12139 fidl::encoding::DefaultFuchsiaResourceDialect,
12140 >,
12141 offset: usize,
12142 _depth: fidl::encoding::Depth,
12143 ) -> fidl::Result<()> {
12144 decoder.debug_check_bounds::<Self>(offset);
12145 // Verify that padding bytes are zero.
12146 fidl::decode!(
12147 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12148 fidl::encoding::DefaultFuchsiaResourceDialect,
12149 &mut self.token_request,
12150 decoder,
12151 offset + 0,
12152 _depth
12153 )?;
12154 Ok(())
12155 }
12156 }
12157
12158 impl fidl::encoding::ResourceTypeMarker for AllocatorBindSharedCollectionRequest {
12159 type Borrowed<'a> = &'a mut Self;
12160 fn take_or_borrow<'a>(
12161 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12162 ) -> Self::Borrowed<'a> {
12163 value
12164 }
12165 }
12166
12167 unsafe impl fidl::encoding::TypeMarker for AllocatorBindSharedCollectionRequest {
12168 type Owned = Self;
12169
12170 #[inline(always)]
12171 fn inline_align(_context: fidl::encoding::Context) -> usize {
12172 4
12173 }
12174
12175 #[inline(always)]
12176 fn inline_size(_context: fidl::encoding::Context) -> usize {
12177 8
12178 }
12179 }
12180
12181 unsafe impl
12182 fidl::encoding::Encode<
12183 AllocatorBindSharedCollectionRequest,
12184 fidl::encoding::DefaultFuchsiaResourceDialect,
12185 > for &mut AllocatorBindSharedCollectionRequest
12186 {
12187 #[inline]
12188 unsafe fn encode(
12189 self,
12190 encoder: &mut fidl::encoding::Encoder<
12191 '_,
12192 fidl::encoding::DefaultFuchsiaResourceDialect,
12193 >,
12194 offset: usize,
12195 _depth: fidl::encoding::Depth,
12196 ) -> fidl::Result<()> {
12197 encoder.debug_check_bounds::<AllocatorBindSharedCollectionRequest>(offset);
12198 // Delegate to tuple encoding.
12199 fidl::encoding::Encode::<AllocatorBindSharedCollectionRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
12200 (
12201 <fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.token),
12202 <fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffer_collection_request),
12203 ),
12204 encoder, offset, _depth
12205 )
12206 }
12207 }
12208 unsafe impl<
12209 T0: fidl::encoding::Encode<
12210 fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
12211 fidl::encoding::DefaultFuchsiaResourceDialect,
12212 >,
12213 T1: fidl::encoding::Encode<
12214 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12215 fidl::encoding::DefaultFuchsiaResourceDialect,
12216 >,
12217 >
12218 fidl::encoding::Encode<
12219 AllocatorBindSharedCollectionRequest,
12220 fidl::encoding::DefaultFuchsiaResourceDialect,
12221 > for (T0, T1)
12222 {
12223 #[inline]
12224 unsafe fn encode(
12225 self,
12226 encoder: &mut fidl::encoding::Encoder<
12227 '_,
12228 fidl::encoding::DefaultFuchsiaResourceDialect,
12229 >,
12230 offset: usize,
12231 depth: fidl::encoding::Depth,
12232 ) -> fidl::Result<()> {
12233 encoder.debug_check_bounds::<AllocatorBindSharedCollectionRequest>(offset);
12234 // Zero out padding regions. There's no need to apply masks
12235 // because the unmasked parts will be overwritten by fields.
12236 // Write the fields.
12237 self.0.encode(encoder, offset + 0, depth)?;
12238 self.1.encode(encoder, offset + 4, depth)?;
12239 Ok(())
12240 }
12241 }
12242
12243 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12244 for AllocatorBindSharedCollectionRequest
12245 {
12246 #[inline(always)]
12247 fn new_empty() -> Self {
12248 Self {
12249 token: fidl::new_empty!(
12250 fidl::encoding::Endpoint<
12251 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
12252 >,
12253 fidl::encoding::DefaultFuchsiaResourceDialect
12254 ),
12255 buffer_collection_request: fidl::new_empty!(
12256 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12257 fidl::encoding::DefaultFuchsiaResourceDialect
12258 ),
12259 }
12260 }
12261
12262 #[inline]
12263 unsafe fn decode(
12264 &mut self,
12265 decoder: &mut fidl::encoding::Decoder<
12266 '_,
12267 fidl::encoding::DefaultFuchsiaResourceDialect,
12268 >,
12269 offset: usize,
12270 _depth: fidl::encoding::Depth,
12271 ) -> fidl::Result<()> {
12272 decoder.debug_check_bounds::<Self>(offset);
12273 // Verify that padding bytes are zero.
12274 fidl::decode!(
12275 fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
12276 fidl::encoding::DefaultFuchsiaResourceDialect,
12277 &mut self.token,
12278 decoder,
12279 offset + 0,
12280 _depth
12281 )?;
12282 fidl::decode!(
12283 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12284 fidl::encoding::DefaultFuchsiaResourceDialect,
12285 &mut self.buffer_collection_request,
12286 decoder,
12287 offset + 4,
12288 _depth
12289 )?;
12290 Ok(())
12291 }
12292 }
12293
12294 impl fidl::encoding::ResourceTypeMarker for AllocatorConnectToSysmem2AllocatorRequest {
12295 type Borrowed<'a> = &'a mut Self;
12296 fn take_or_borrow<'a>(
12297 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12298 ) -> Self::Borrowed<'a> {
12299 value
12300 }
12301 }
12302
12303 unsafe impl fidl::encoding::TypeMarker for AllocatorConnectToSysmem2AllocatorRequest {
12304 type Owned = Self;
12305
12306 #[inline(always)]
12307 fn inline_align(_context: fidl::encoding::Context) -> usize {
12308 4
12309 }
12310
12311 #[inline(always)]
12312 fn inline_size(_context: fidl::encoding::Context) -> usize {
12313 4
12314 }
12315 }
12316
12317 unsafe impl
12318 fidl::encoding::Encode<
12319 AllocatorConnectToSysmem2AllocatorRequest,
12320 fidl::encoding::DefaultFuchsiaResourceDialect,
12321 > for &mut AllocatorConnectToSysmem2AllocatorRequest
12322 {
12323 #[inline]
12324 unsafe fn encode(
12325 self,
12326 encoder: &mut fidl::encoding::Encoder<
12327 '_,
12328 fidl::encoding::DefaultFuchsiaResourceDialect,
12329 >,
12330 offset: usize,
12331 _depth: fidl::encoding::Depth,
12332 ) -> fidl::Result<()> {
12333 encoder.debug_check_bounds::<AllocatorConnectToSysmem2AllocatorRequest>(offset);
12334 // Delegate to tuple encoding.
12335 fidl::encoding::Encode::<
12336 AllocatorConnectToSysmem2AllocatorRequest,
12337 fidl::encoding::DefaultFuchsiaResourceDialect,
12338 >::encode(
12339 (<fidl::encoding::Endpoint<
12340 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12341 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12342 &mut self.allocator_request,
12343 ),),
12344 encoder,
12345 offset,
12346 _depth,
12347 )
12348 }
12349 }
12350 unsafe impl<
12351 T0: fidl::encoding::Encode<
12352 fidl::encoding::Endpoint<
12353 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12354 >,
12355 fidl::encoding::DefaultFuchsiaResourceDialect,
12356 >,
12357 >
12358 fidl::encoding::Encode<
12359 AllocatorConnectToSysmem2AllocatorRequest,
12360 fidl::encoding::DefaultFuchsiaResourceDialect,
12361 > for (T0,)
12362 {
12363 #[inline]
12364 unsafe fn encode(
12365 self,
12366 encoder: &mut fidl::encoding::Encoder<
12367 '_,
12368 fidl::encoding::DefaultFuchsiaResourceDialect,
12369 >,
12370 offset: usize,
12371 depth: fidl::encoding::Depth,
12372 ) -> fidl::Result<()> {
12373 encoder.debug_check_bounds::<AllocatorConnectToSysmem2AllocatorRequest>(offset);
12374 // Zero out padding regions. There's no need to apply masks
12375 // because the unmasked parts will be overwritten by fields.
12376 // Write the fields.
12377 self.0.encode(encoder, offset + 0, depth)?;
12378 Ok(())
12379 }
12380 }
12381
12382 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12383 for AllocatorConnectToSysmem2AllocatorRequest
12384 {
12385 #[inline(always)]
12386 fn new_empty() -> Self {
12387 Self {
12388 allocator_request: fidl::new_empty!(
12389 fidl::encoding::Endpoint<
12390 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12391 >,
12392 fidl::encoding::DefaultFuchsiaResourceDialect
12393 ),
12394 }
12395 }
12396
12397 #[inline]
12398 unsafe fn decode(
12399 &mut self,
12400 decoder: &mut fidl::encoding::Decoder<
12401 '_,
12402 fidl::encoding::DefaultFuchsiaResourceDialect,
12403 >,
12404 offset: usize,
12405 _depth: fidl::encoding::Depth,
12406 ) -> fidl::Result<()> {
12407 decoder.debug_check_bounds::<Self>(offset);
12408 // Verify that padding bytes are zero.
12409 fidl::decode!(
12410 fidl::encoding::Endpoint<
12411 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12412 >,
12413 fidl::encoding::DefaultFuchsiaResourceDialect,
12414 &mut self.allocator_request,
12415 decoder,
12416 offset + 0,
12417 _depth
12418 )?;
12419 Ok(())
12420 }
12421 }
12422
12423 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
12424 type Borrowed<'a> = &'a mut Self;
12425 fn take_or_borrow<'a>(
12426 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12427 ) -> Self::Borrowed<'a> {
12428 value
12429 }
12430 }
12431
12432 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
12433 type Owned = Self;
12434
12435 #[inline(always)]
12436 fn inline_align(_context: fidl::encoding::Context) -> usize {
12437 4
12438 }
12439
12440 #[inline(always)]
12441 fn inline_size(_context: fidl::encoding::Context) -> usize {
12442 8
12443 }
12444 }
12445
12446 unsafe impl
12447 fidl::encoding::Encode<
12448 BufferCollectionAttachLifetimeTrackingRequest,
12449 fidl::encoding::DefaultFuchsiaResourceDialect,
12450 > for &mut BufferCollectionAttachLifetimeTrackingRequest
12451 {
12452 #[inline]
12453 unsafe fn encode(
12454 self,
12455 encoder: &mut fidl::encoding::Encoder<
12456 '_,
12457 fidl::encoding::DefaultFuchsiaResourceDialect,
12458 >,
12459 offset: usize,
12460 _depth: fidl::encoding::Depth,
12461 ) -> fidl::Result<()> {
12462 encoder.debug_check_bounds::<BufferCollectionAttachLifetimeTrackingRequest>(offset);
12463 // Delegate to tuple encoding.
12464 fidl::encoding::Encode::<
12465 BufferCollectionAttachLifetimeTrackingRequest,
12466 fidl::encoding::DefaultFuchsiaResourceDialect,
12467 >::encode(
12468 (
12469 <fidl::encoding::HandleType<
12470 fidl::EventPair,
12471 { fidl::ObjectType::EVENTPAIR.into_raw() },
12472 2147483648,
12473 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12474 &mut self.server_end
12475 ),
12476 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffers_remaining),
12477 ),
12478 encoder,
12479 offset,
12480 _depth,
12481 )
12482 }
12483 }
12484 unsafe impl<
12485 T0: fidl::encoding::Encode<
12486 fidl::encoding::HandleType<
12487 fidl::EventPair,
12488 { fidl::ObjectType::EVENTPAIR.into_raw() },
12489 2147483648,
12490 >,
12491 fidl::encoding::DefaultFuchsiaResourceDialect,
12492 >,
12493 T1: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12494 >
12495 fidl::encoding::Encode<
12496 BufferCollectionAttachLifetimeTrackingRequest,
12497 fidl::encoding::DefaultFuchsiaResourceDialect,
12498 > for (T0, T1)
12499 {
12500 #[inline]
12501 unsafe fn encode(
12502 self,
12503 encoder: &mut fidl::encoding::Encoder<
12504 '_,
12505 fidl::encoding::DefaultFuchsiaResourceDialect,
12506 >,
12507 offset: usize,
12508 depth: fidl::encoding::Depth,
12509 ) -> fidl::Result<()> {
12510 encoder.debug_check_bounds::<BufferCollectionAttachLifetimeTrackingRequest>(offset);
12511 // Zero out padding regions. There's no need to apply masks
12512 // because the unmasked parts will be overwritten by fields.
12513 // Write the fields.
12514 self.0.encode(encoder, offset + 0, depth)?;
12515 self.1.encode(encoder, offset + 4, depth)?;
12516 Ok(())
12517 }
12518 }
12519
12520 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12521 for BufferCollectionAttachLifetimeTrackingRequest
12522 {
12523 #[inline(always)]
12524 fn new_empty() -> Self {
12525 Self {
12526 server_end: fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
12527 buffers_remaining: fidl::new_empty!(
12528 u32,
12529 fidl::encoding::DefaultFuchsiaResourceDialect
12530 ),
12531 }
12532 }
12533
12534 #[inline]
12535 unsafe fn decode(
12536 &mut self,
12537 decoder: &mut fidl::encoding::Decoder<
12538 '_,
12539 fidl::encoding::DefaultFuchsiaResourceDialect,
12540 >,
12541 offset: usize,
12542 _depth: fidl::encoding::Depth,
12543 ) -> fidl::Result<()> {
12544 decoder.debug_check_bounds::<Self>(offset);
12545 // Verify that padding bytes are zero.
12546 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.server_end, decoder, offset + 0, _depth)?;
12547 fidl::decode!(
12548 u32,
12549 fidl::encoding::DefaultFuchsiaResourceDialect,
12550 &mut self.buffers_remaining,
12551 decoder,
12552 offset + 4,
12553 _depth
12554 )?;
12555 Ok(())
12556 }
12557 }
12558
12559 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachTokenRequest {
12560 type Borrowed<'a> = &'a mut Self;
12561 fn take_or_borrow<'a>(
12562 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12563 ) -> Self::Borrowed<'a> {
12564 value
12565 }
12566 }
12567
12568 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachTokenRequest {
12569 type Owned = Self;
12570
12571 #[inline(always)]
12572 fn inline_align(_context: fidl::encoding::Context) -> usize {
12573 4
12574 }
12575
12576 #[inline(always)]
12577 fn inline_size(_context: fidl::encoding::Context) -> usize {
12578 8
12579 }
12580 }
12581
12582 unsafe impl
12583 fidl::encoding::Encode<
12584 BufferCollectionAttachTokenRequest,
12585 fidl::encoding::DefaultFuchsiaResourceDialect,
12586 > for &mut BufferCollectionAttachTokenRequest
12587 {
12588 #[inline]
12589 unsafe fn encode(
12590 self,
12591 encoder: &mut fidl::encoding::Encoder<
12592 '_,
12593 fidl::encoding::DefaultFuchsiaResourceDialect,
12594 >,
12595 offset: usize,
12596 _depth: fidl::encoding::Depth,
12597 ) -> fidl::Result<()> {
12598 encoder.debug_check_bounds::<BufferCollectionAttachTokenRequest>(offset);
12599 // Delegate to tuple encoding.
12600 fidl::encoding::Encode::<
12601 BufferCollectionAttachTokenRequest,
12602 fidl::encoding::DefaultFuchsiaResourceDialect,
12603 >::encode(
12604 (
12605 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.rights_attenuation_mask),
12606 <fidl::encoding::Endpoint<
12607 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12608 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12609 &mut self.token_request,
12610 ),
12611 ),
12612 encoder,
12613 offset,
12614 _depth,
12615 )
12616 }
12617 }
12618 unsafe impl<
12619 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12620 T1: fidl::encoding::Encode<
12621 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12622 fidl::encoding::DefaultFuchsiaResourceDialect,
12623 >,
12624 >
12625 fidl::encoding::Encode<
12626 BufferCollectionAttachTokenRequest,
12627 fidl::encoding::DefaultFuchsiaResourceDialect,
12628 > for (T0, T1)
12629 {
12630 #[inline]
12631 unsafe fn encode(
12632 self,
12633 encoder: &mut fidl::encoding::Encoder<
12634 '_,
12635 fidl::encoding::DefaultFuchsiaResourceDialect,
12636 >,
12637 offset: usize,
12638 depth: fidl::encoding::Depth,
12639 ) -> fidl::Result<()> {
12640 encoder.debug_check_bounds::<BufferCollectionAttachTokenRequest>(offset);
12641 // Zero out padding regions. There's no need to apply masks
12642 // because the unmasked parts will be overwritten by fields.
12643 // Write the fields.
12644 self.0.encode(encoder, offset + 0, depth)?;
12645 self.1.encode(encoder, offset + 4, depth)?;
12646 Ok(())
12647 }
12648 }
12649
12650 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12651 for BufferCollectionAttachTokenRequest
12652 {
12653 #[inline(always)]
12654 fn new_empty() -> Self {
12655 Self {
12656 rights_attenuation_mask: fidl::new_empty!(
12657 u32,
12658 fidl::encoding::DefaultFuchsiaResourceDialect
12659 ),
12660 token_request: fidl::new_empty!(
12661 fidl::encoding::Endpoint<
12662 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12663 >,
12664 fidl::encoding::DefaultFuchsiaResourceDialect
12665 ),
12666 }
12667 }
12668
12669 #[inline]
12670 unsafe fn decode(
12671 &mut self,
12672 decoder: &mut fidl::encoding::Decoder<
12673 '_,
12674 fidl::encoding::DefaultFuchsiaResourceDialect,
12675 >,
12676 offset: usize,
12677 _depth: fidl::encoding::Depth,
12678 ) -> fidl::Result<()> {
12679 decoder.debug_check_bounds::<Self>(offset);
12680 // Verify that padding bytes are zero.
12681 fidl::decode!(
12682 u32,
12683 fidl::encoding::DefaultFuchsiaResourceDialect,
12684 &mut self.rights_attenuation_mask,
12685 decoder,
12686 offset + 0,
12687 _depth
12688 )?;
12689 fidl::decode!(
12690 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12691 fidl::encoding::DefaultFuchsiaResourceDialect,
12692 &mut self.token_request,
12693 decoder,
12694 offset + 4,
12695 _depth
12696 )?;
12697 Ok(())
12698 }
12699 }
12700
12701 impl fidl::encoding::ResourceTypeMarker for BufferCollectionInfo {
12702 type Borrowed<'a> = &'a mut Self;
12703 fn take_or_borrow<'a>(
12704 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12705 ) -> Self::Borrowed<'a> {
12706 value
12707 }
12708 }
12709
12710 unsafe impl fidl::encoding::TypeMarker for BufferCollectionInfo {
12711 type Owned = Self;
12712
12713 #[inline(always)]
12714 fn inline_align(_context: fidl::encoding::Context) -> usize {
12715 8
12716 }
12717
12718 #[inline(always)]
12719 fn inline_size(_context: fidl::encoding::Context) -> usize {
12720 352
12721 }
12722 }
12723
12724 unsafe impl
12725 fidl::encoding::Encode<BufferCollectionInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
12726 for &mut BufferCollectionInfo
12727 {
12728 #[inline]
12729 unsafe fn encode(
12730 self,
12731 encoder: &mut fidl::encoding::Encoder<
12732 '_,
12733 fidl::encoding::DefaultFuchsiaResourceDialect,
12734 >,
12735 offset: usize,
12736 _depth: fidl::encoding::Depth,
12737 ) -> fidl::Result<()> {
12738 encoder.debug_check_bounds::<BufferCollectionInfo>(offset);
12739 // Delegate to tuple encoding.
12740 fidl::encoding::Encode::<
12741 BufferCollectionInfo,
12742 fidl::encoding::DefaultFuchsiaResourceDialect,
12743 >::encode(
12744 (
12745 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffer_count),
12746 <BufferFormat as fidl::encoding::ValueTypeMarker>::borrow(&self.format),
12747 <fidl::encoding::Array<
12748 fidl::encoding::Optional<
12749 fidl::encoding::HandleType<
12750 fidl::Vmo,
12751 { fidl::ObjectType::VMO.into_raw() },
12752 2147483648,
12753 >,
12754 >,
12755 64,
12756 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12757 &mut self.vmos
12758 ),
12759 <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.vmo_size),
12760 ),
12761 encoder,
12762 offset,
12763 _depth,
12764 )
12765 }
12766 }
12767 unsafe impl<
12768 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12769 T1: fidl::encoding::Encode<BufferFormat, fidl::encoding::DefaultFuchsiaResourceDialect>,
12770 T2: fidl::encoding::Encode<
12771 fidl::encoding::Array<
12772 fidl::encoding::Optional<
12773 fidl::encoding::HandleType<
12774 fidl::Vmo,
12775 { fidl::ObjectType::VMO.into_raw() },
12776 2147483648,
12777 >,
12778 >,
12779 64,
12780 >,
12781 fidl::encoding::DefaultFuchsiaResourceDialect,
12782 >,
12783 T3: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
12784 >
12785 fidl::encoding::Encode<BufferCollectionInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
12786 for (T0, T1, T2, T3)
12787 {
12788 #[inline]
12789 unsafe fn encode(
12790 self,
12791 encoder: &mut fidl::encoding::Encoder<
12792 '_,
12793 fidl::encoding::DefaultFuchsiaResourceDialect,
12794 >,
12795 offset: usize,
12796 depth: fidl::encoding::Depth,
12797 ) -> fidl::Result<()> {
12798 encoder.debug_check_bounds::<BufferCollectionInfo>(offset);
12799 // Zero out padding regions. There's no need to apply masks
12800 // because the unmasked parts will be overwritten by fields.
12801 unsafe {
12802 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
12803 (ptr as *mut u64).write_unaligned(0);
12804 }
12805 // Write the fields.
12806 self.0.encode(encoder, offset + 0, depth)?;
12807 self.1.encode(encoder, offset + 8, depth)?;
12808 self.2.encode(encoder, offset + 88, depth)?;
12809 self.3.encode(encoder, offset + 344, depth)?;
12810 Ok(())
12811 }
12812 }
12813
12814 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12815 for BufferCollectionInfo
12816 {
12817 #[inline(always)]
12818 fn new_empty() -> Self {
12819 Self {
12820 buffer_count: fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect),
12821 format: fidl::new_empty!(
12822 BufferFormat,
12823 fidl::encoding::DefaultFuchsiaResourceDialect
12824 ),
12825 vmos: fidl::new_empty!(
12826 fidl::encoding::Array<
12827 fidl::encoding::Optional<
12828 fidl::encoding::HandleType<
12829 fidl::Vmo,
12830 { fidl::ObjectType::VMO.into_raw() },
12831 2147483648,
12832 >,
12833 >,
12834 64,
12835 >,
12836 fidl::encoding::DefaultFuchsiaResourceDialect
12837 ),
12838 vmo_size: fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect),
12839 }
12840 }
12841
12842 #[inline]
12843 unsafe fn decode(
12844 &mut self,
12845 decoder: &mut fidl::encoding::Decoder<
12846 '_,
12847 fidl::encoding::DefaultFuchsiaResourceDialect,
12848 >,
12849 offset: usize,
12850 _depth: fidl::encoding::Depth,
12851 ) -> fidl::Result<()> {
12852 decoder.debug_check_bounds::<Self>(offset);
12853 // Verify that padding bytes are zero.
12854 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
12855 let padval = unsafe { (ptr as *const u64).read_unaligned() };
12856 let mask = 0xffffffff00000000u64;
12857 let maskedval = padval & mask;
12858 if maskedval != 0 {
12859 return Err(fidl::Error::NonZeroPadding {
12860 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
12861 });
12862 }
12863 fidl::decode!(
12864 u32,
12865 fidl::encoding::DefaultFuchsiaResourceDialect,
12866 &mut self.buffer_count,
12867 decoder,
12868 offset + 0,
12869 _depth
12870 )?;
12871 fidl::decode!(
12872 BufferFormat,
12873 fidl::encoding::DefaultFuchsiaResourceDialect,
12874 &mut self.format,
12875 decoder,
12876 offset + 8,
12877 _depth
12878 )?;
12879 fidl::decode!(
12880 fidl::encoding::Array<
12881 fidl::encoding::Optional<
12882 fidl::encoding::HandleType<
12883 fidl::Vmo,
12884 { fidl::ObjectType::VMO.into_raw() },
12885 2147483648,
12886 >,
12887 >,
12888 64,
12889 >,
12890 fidl::encoding::DefaultFuchsiaResourceDialect,
12891 &mut self.vmos,
12892 decoder,
12893 offset + 88,
12894 _depth
12895 )?;
12896 fidl::decode!(
12897 u64,
12898 fidl::encoding::DefaultFuchsiaResourceDialect,
12899 &mut self.vmo_size,
12900 decoder,
12901 offset + 344,
12902 _depth
12903 )?;
12904 Ok(())
12905 }
12906 }
12907
12908 impl fidl::encoding::ResourceTypeMarker for BufferCollectionInfo2 {
12909 type Borrowed<'a> = &'a mut Self;
12910 fn take_or_borrow<'a>(
12911 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12912 ) -> Self::Borrowed<'a> {
12913 value
12914 }
12915 }
12916
12917 unsafe impl fidl::encoding::TypeMarker for BufferCollectionInfo2 {
12918 type Owned = Self;
12919
12920 #[inline(always)]
12921 fn inline_align(_context: fidl::encoding::Context) -> usize {
12922 8
12923 }
12924
12925 #[inline(always)]
12926 fn inline_size(_context: fidl::encoding::Context) -> usize {
12927 1296
12928 }
12929 }
12930
12931 unsafe impl
12932 fidl::encoding::Encode<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>
12933 for &mut BufferCollectionInfo2
12934 {
12935 #[inline]
12936 unsafe fn encode(
12937 self,
12938 encoder: &mut fidl::encoding::Encoder<
12939 '_,
12940 fidl::encoding::DefaultFuchsiaResourceDialect,
12941 >,
12942 offset: usize,
12943 _depth: fidl::encoding::Depth,
12944 ) -> fidl::Result<()> {
12945 encoder.debug_check_bounds::<BufferCollectionInfo2>(offset);
12946 // Delegate to tuple encoding.
12947 fidl::encoding::Encode::<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
12948 (
12949 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffer_count),
12950 <SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow(&self.settings),
12951 <fidl::encoding::Array<VmoBuffer, 64> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffers),
12952 ),
12953 encoder, offset, _depth
12954 )
12955 }
12956 }
12957 unsafe impl<
12958 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12959 T1: fidl::encoding::Encode<SingleBufferSettings, fidl::encoding::DefaultFuchsiaResourceDialect>,
12960 T2: fidl::encoding::Encode<
12961 fidl::encoding::Array<VmoBuffer, 64>,
12962 fidl::encoding::DefaultFuchsiaResourceDialect,
12963 >,
12964 >
12965 fidl::encoding::Encode<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>
12966 for (T0, T1, T2)
12967 {
12968 #[inline]
12969 unsafe fn encode(
12970 self,
12971 encoder: &mut fidl::encoding::Encoder<
12972 '_,
12973 fidl::encoding::DefaultFuchsiaResourceDialect,
12974 >,
12975 offset: usize,
12976 depth: fidl::encoding::Depth,
12977 ) -> fidl::Result<()> {
12978 encoder.debug_check_bounds::<BufferCollectionInfo2>(offset);
12979 // Zero out padding regions. There's no need to apply masks
12980 // because the unmasked parts will be overwritten by fields.
12981 unsafe {
12982 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
12983 (ptr as *mut u64).write_unaligned(0);
12984 }
12985 // Write the fields.
12986 self.0.encode(encoder, offset + 0, depth)?;
12987 self.1.encode(encoder, offset + 8, depth)?;
12988 self.2.encode(encoder, offset + 272, depth)?;
12989 Ok(())
12990 }
12991 }
12992
12993 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12994 for BufferCollectionInfo2
12995 {
12996 #[inline(always)]
12997 fn new_empty() -> Self {
12998 Self {
12999 buffer_count: fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect),
13000 settings: fidl::new_empty!(
13001 SingleBufferSettings,
13002 fidl::encoding::DefaultFuchsiaResourceDialect
13003 ),
13004 buffers: fidl::new_empty!(fidl::encoding::Array<VmoBuffer, 64>, fidl::encoding::DefaultFuchsiaResourceDialect),
13005 }
13006 }
13007
13008 #[inline]
13009 unsafe fn decode(
13010 &mut self,
13011 decoder: &mut fidl::encoding::Decoder<
13012 '_,
13013 fidl::encoding::DefaultFuchsiaResourceDialect,
13014 >,
13015 offset: usize,
13016 _depth: fidl::encoding::Depth,
13017 ) -> fidl::Result<()> {
13018 decoder.debug_check_bounds::<Self>(offset);
13019 // Verify that padding bytes are zero.
13020 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
13021 let padval = unsafe { (ptr as *const u64).read_unaligned() };
13022 let mask = 0xffffffff00000000u64;
13023 let maskedval = padval & mask;
13024 if maskedval != 0 {
13025 return Err(fidl::Error::NonZeroPadding {
13026 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
13027 });
13028 }
13029 fidl::decode!(
13030 u32,
13031 fidl::encoding::DefaultFuchsiaResourceDialect,
13032 &mut self.buffer_count,
13033 decoder,
13034 offset + 0,
13035 _depth
13036 )?;
13037 fidl::decode!(
13038 SingleBufferSettings,
13039 fidl::encoding::DefaultFuchsiaResourceDialect,
13040 &mut self.settings,
13041 decoder,
13042 offset + 8,
13043 _depth
13044 )?;
13045 fidl::decode!(fidl::encoding::Array<VmoBuffer, 64>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.buffers, decoder, offset + 272, _depth)?;
13046 Ok(())
13047 }
13048 }
13049
13050 impl fidl::encoding::ResourceTypeMarker
13051 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13052 {
13053 type Borrowed<'a> = &'a mut Self;
13054 fn take_or_borrow<'a>(
13055 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13056 ) -> Self::Borrowed<'a> {
13057 value
13058 }
13059 }
13060
13061 unsafe impl fidl::encoding::TypeMarker
13062 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13063 {
13064 type Owned = Self;
13065
13066 #[inline(always)]
13067 fn inline_align(_context: fidl::encoding::Context) -> usize {
13068 4
13069 }
13070
13071 #[inline(always)]
13072 fn inline_size(_context: fidl::encoding::Context) -> usize {
13073 4
13074 }
13075 }
13076
13077 unsafe impl
13078 fidl::encoding::Encode<
13079 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13080 fidl::encoding::DefaultFuchsiaResourceDialect,
13081 > for &mut BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13082 {
13083 #[inline]
13084 unsafe fn encode(
13085 self,
13086 encoder: &mut fidl::encoding::Encoder<
13087 '_,
13088 fidl::encoding::DefaultFuchsiaResourceDialect,
13089 >,
13090 offset: usize,
13091 _depth: fidl::encoding::Depth,
13092 ) -> fidl::Result<()> {
13093 encoder
13094 .debug_check_bounds::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
13095 offset,
13096 );
13097 // Delegate to tuple encoding.
13098 fidl::encoding::Encode::<
13099 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13100 fidl::encoding::DefaultFuchsiaResourceDialect,
13101 >::encode(
13102 (<fidl::encoding::Endpoint<
13103 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13104 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13105 &mut self.group_request
13106 ),),
13107 encoder,
13108 offset,
13109 _depth,
13110 )
13111 }
13112 }
13113 unsafe impl<
13114 T0: fidl::encoding::Encode<
13115 fidl::encoding::Endpoint<
13116 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13117 >,
13118 fidl::encoding::DefaultFuchsiaResourceDialect,
13119 >,
13120 >
13121 fidl::encoding::Encode<
13122 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13123 fidl::encoding::DefaultFuchsiaResourceDialect,
13124 > for (T0,)
13125 {
13126 #[inline]
13127 unsafe fn encode(
13128 self,
13129 encoder: &mut fidl::encoding::Encoder<
13130 '_,
13131 fidl::encoding::DefaultFuchsiaResourceDialect,
13132 >,
13133 offset: usize,
13134 depth: fidl::encoding::Depth,
13135 ) -> fidl::Result<()> {
13136 encoder
13137 .debug_check_bounds::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
13138 offset,
13139 );
13140 // Zero out padding regions. There's no need to apply masks
13141 // because the unmasked parts will be overwritten by fields.
13142 // Write the fields.
13143 self.0.encode(encoder, offset + 0, depth)?;
13144 Ok(())
13145 }
13146 }
13147
13148 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13149 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13150 {
13151 #[inline(always)]
13152 fn new_empty() -> Self {
13153 Self {
13154 group_request: fidl::new_empty!(
13155 fidl::encoding::Endpoint<
13156 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13157 >,
13158 fidl::encoding::DefaultFuchsiaResourceDialect
13159 ),
13160 }
13161 }
13162
13163 #[inline]
13164 unsafe fn decode(
13165 &mut self,
13166 decoder: &mut fidl::encoding::Decoder<
13167 '_,
13168 fidl::encoding::DefaultFuchsiaResourceDialect,
13169 >,
13170 offset: usize,
13171 _depth: fidl::encoding::Depth,
13172 ) -> fidl::Result<()> {
13173 decoder.debug_check_bounds::<Self>(offset);
13174 // Verify that padding bytes are zero.
13175 fidl::decode!(
13176 fidl::encoding::Endpoint<
13177 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13178 >,
13179 fidl::encoding::DefaultFuchsiaResourceDialect,
13180 &mut self.group_request,
13181 decoder,
13182 offset + 0,
13183 _depth
13184 )?;
13185 Ok(())
13186 }
13187 }
13188
13189 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateRequest {
13190 type Borrowed<'a> = &'a mut Self;
13191 fn take_or_borrow<'a>(
13192 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13193 ) -> Self::Borrowed<'a> {
13194 value
13195 }
13196 }
13197
13198 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateRequest {
13199 type Owned = Self;
13200
13201 #[inline(always)]
13202 fn inline_align(_context: fidl::encoding::Context) -> usize {
13203 4
13204 }
13205
13206 #[inline(always)]
13207 fn inline_size(_context: fidl::encoding::Context) -> usize {
13208 8
13209 }
13210 }
13211
13212 unsafe impl
13213 fidl::encoding::Encode<
13214 BufferCollectionTokenDuplicateRequest,
13215 fidl::encoding::DefaultFuchsiaResourceDialect,
13216 > for &mut BufferCollectionTokenDuplicateRequest
13217 {
13218 #[inline]
13219 unsafe fn encode(
13220 self,
13221 encoder: &mut fidl::encoding::Encoder<
13222 '_,
13223 fidl::encoding::DefaultFuchsiaResourceDialect,
13224 >,
13225 offset: usize,
13226 _depth: fidl::encoding::Depth,
13227 ) -> fidl::Result<()> {
13228 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateRequest>(offset);
13229 // Delegate to tuple encoding.
13230 fidl::encoding::Encode::<
13231 BufferCollectionTokenDuplicateRequest,
13232 fidl::encoding::DefaultFuchsiaResourceDialect,
13233 >::encode(
13234 (
13235 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.rights_attenuation_mask),
13236 <fidl::encoding::Endpoint<
13237 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
13238 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13239 &mut self.token_request,
13240 ),
13241 ),
13242 encoder,
13243 offset,
13244 _depth,
13245 )
13246 }
13247 }
13248 unsafe impl<
13249 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13250 T1: fidl::encoding::Encode<
13251 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
13252 fidl::encoding::DefaultFuchsiaResourceDialect,
13253 >,
13254 >
13255 fidl::encoding::Encode<
13256 BufferCollectionTokenDuplicateRequest,
13257 fidl::encoding::DefaultFuchsiaResourceDialect,
13258 > for (T0, T1)
13259 {
13260 #[inline]
13261 unsafe fn encode(
13262 self,
13263 encoder: &mut fidl::encoding::Encoder<
13264 '_,
13265 fidl::encoding::DefaultFuchsiaResourceDialect,
13266 >,
13267 offset: usize,
13268 depth: fidl::encoding::Depth,
13269 ) -> fidl::Result<()> {
13270 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateRequest>(offset);
13271 // Zero out padding regions. There's no need to apply masks
13272 // because the unmasked parts will be overwritten by fields.
13273 // Write the fields.
13274 self.0.encode(encoder, offset + 0, depth)?;
13275 self.1.encode(encoder, offset + 4, depth)?;
13276 Ok(())
13277 }
13278 }
13279
13280 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13281 for BufferCollectionTokenDuplicateRequest
13282 {
13283 #[inline(always)]
13284 fn new_empty() -> Self {
13285 Self {
13286 rights_attenuation_mask: fidl::new_empty!(
13287 u32,
13288 fidl::encoding::DefaultFuchsiaResourceDialect
13289 ),
13290 token_request: fidl::new_empty!(
13291 fidl::encoding::Endpoint<
13292 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
13293 >,
13294 fidl::encoding::DefaultFuchsiaResourceDialect
13295 ),
13296 }
13297 }
13298
13299 #[inline]
13300 unsafe fn decode(
13301 &mut self,
13302 decoder: &mut fidl::encoding::Decoder<
13303 '_,
13304 fidl::encoding::DefaultFuchsiaResourceDialect,
13305 >,
13306 offset: usize,
13307 _depth: fidl::encoding::Depth,
13308 ) -> fidl::Result<()> {
13309 decoder.debug_check_bounds::<Self>(offset);
13310 // Verify that padding bytes are zero.
13311 fidl::decode!(
13312 u32,
13313 fidl::encoding::DefaultFuchsiaResourceDialect,
13314 &mut self.rights_attenuation_mask,
13315 decoder,
13316 offset + 0,
13317 _depth
13318 )?;
13319 fidl::decode!(
13320 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
13321 fidl::encoding::DefaultFuchsiaResourceDialect,
13322 &mut self.token_request,
13323 decoder,
13324 offset + 4,
13325 _depth
13326 )?;
13327 Ok(())
13328 }
13329 }
13330
13331 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateSyncResponse {
13332 type Borrowed<'a> = &'a mut Self;
13333 fn take_or_borrow<'a>(
13334 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13335 ) -> Self::Borrowed<'a> {
13336 value
13337 }
13338 }
13339
13340 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateSyncResponse {
13341 type Owned = Self;
13342
13343 #[inline(always)]
13344 fn inline_align(_context: fidl::encoding::Context) -> usize {
13345 8
13346 }
13347
13348 #[inline(always)]
13349 fn inline_size(_context: fidl::encoding::Context) -> usize {
13350 16
13351 }
13352 }
13353
13354 unsafe impl
13355 fidl::encoding::Encode<
13356 BufferCollectionTokenDuplicateSyncResponse,
13357 fidl::encoding::DefaultFuchsiaResourceDialect,
13358 > for &mut BufferCollectionTokenDuplicateSyncResponse
13359 {
13360 #[inline]
13361 unsafe fn encode(
13362 self,
13363 encoder: &mut fidl::encoding::Encoder<
13364 '_,
13365 fidl::encoding::DefaultFuchsiaResourceDialect,
13366 >,
13367 offset: usize,
13368 _depth: fidl::encoding::Depth,
13369 ) -> fidl::Result<()> {
13370 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateSyncResponse>(offset);
13371 // Delegate to tuple encoding.
13372 fidl::encoding::Encode::<
13373 BufferCollectionTokenDuplicateSyncResponse,
13374 fidl::encoding::DefaultFuchsiaResourceDialect,
13375 >::encode(
13376 (<fidl::encoding::Vector<
13377 fidl::encoding::Endpoint<
13378 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13379 >,
13380 64,
13381 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13382 &mut self.tokens
13383 ),),
13384 encoder,
13385 offset,
13386 _depth,
13387 )
13388 }
13389 }
13390 unsafe impl<
13391 T0: fidl::encoding::Encode<
13392 fidl::encoding::Vector<
13393 fidl::encoding::Endpoint<
13394 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13395 >,
13396 64,
13397 >,
13398 fidl::encoding::DefaultFuchsiaResourceDialect,
13399 >,
13400 >
13401 fidl::encoding::Encode<
13402 BufferCollectionTokenDuplicateSyncResponse,
13403 fidl::encoding::DefaultFuchsiaResourceDialect,
13404 > for (T0,)
13405 {
13406 #[inline]
13407 unsafe fn encode(
13408 self,
13409 encoder: &mut fidl::encoding::Encoder<
13410 '_,
13411 fidl::encoding::DefaultFuchsiaResourceDialect,
13412 >,
13413 offset: usize,
13414 depth: fidl::encoding::Depth,
13415 ) -> fidl::Result<()> {
13416 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateSyncResponse>(offset);
13417 // Zero out padding regions. There's no need to apply masks
13418 // because the unmasked parts will be overwritten by fields.
13419 // Write the fields.
13420 self.0.encode(encoder, offset + 0, depth)?;
13421 Ok(())
13422 }
13423 }
13424
13425 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13426 for BufferCollectionTokenDuplicateSyncResponse
13427 {
13428 #[inline(always)]
13429 fn new_empty() -> Self {
13430 Self {
13431 tokens: fidl::new_empty!(
13432 fidl::encoding::Vector<
13433 fidl::encoding::Endpoint<
13434 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13435 >,
13436 64,
13437 >,
13438 fidl::encoding::DefaultFuchsiaResourceDialect
13439 ),
13440 }
13441 }
13442
13443 #[inline]
13444 unsafe fn decode(
13445 &mut self,
13446 decoder: &mut fidl::encoding::Decoder<
13447 '_,
13448 fidl::encoding::DefaultFuchsiaResourceDialect,
13449 >,
13450 offset: usize,
13451 _depth: fidl::encoding::Depth,
13452 ) -> fidl::Result<()> {
13453 decoder.debug_check_bounds::<Self>(offset);
13454 // Verify that padding bytes are zero.
13455 fidl::decode!(
13456 fidl::encoding::Vector<
13457 fidl::encoding::Endpoint<
13458 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13459 >,
13460 64,
13461 >,
13462 fidl::encoding::DefaultFuchsiaResourceDialect,
13463 &mut self.tokens,
13464 decoder,
13465 offset + 0,
13466 _depth
13467 )?;
13468 Ok(())
13469 }
13470 }
13471
13472 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
13473 type Borrowed<'a> = &'a mut Self;
13474 fn take_or_borrow<'a>(
13475 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13476 ) -> Self::Borrowed<'a> {
13477 value
13478 }
13479 }
13480
13481 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
13482 type Owned = Self;
13483
13484 #[inline(always)]
13485 fn inline_align(_context: fidl::encoding::Context) -> usize {
13486 8
13487 }
13488
13489 #[inline(always)]
13490 fn inline_size(_context: fidl::encoding::Context) -> usize {
13491 16
13492 }
13493 }
13494
13495 unsafe impl
13496 fidl::encoding::Encode<
13497 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13498 fidl::encoding::DefaultFuchsiaResourceDialect,
13499 > for &mut BufferCollectionTokenGroupCreateChildrenSyncResponse
13500 {
13501 #[inline]
13502 unsafe fn encode(
13503 self,
13504 encoder: &mut fidl::encoding::Encoder<
13505 '_,
13506 fidl::encoding::DefaultFuchsiaResourceDialect,
13507 >,
13508 offset: usize,
13509 _depth: fidl::encoding::Depth,
13510 ) -> fidl::Result<()> {
13511 encoder
13512 .debug_check_bounds::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(offset);
13513 // Delegate to tuple encoding.
13514 fidl::encoding::Encode::<
13515 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13516 fidl::encoding::DefaultFuchsiaResourceDialect,
13517 >::encode(
13518 (<fidl::encoding::Vector<
13519 fidl::encoding::Endpoint<
13520 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13521 >,
13522 64,
13523 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13524 &mut self.tokens
13525 ),),
13526 encoder,
13527 offset,
13528 _depth,
13529 )
13530 }
13531 }
13532 unsafe impl<
13533 T0: fidl::encoding::Encode<
13534 fidl::encoding::Vector<
13535 fidl::encoding::Endpoint<
13536 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13537 >,
13538 64,
13539 >,
13540 fidl::encoding::DefaultFuchsiaResourceDialect,
13541 >,
13542 >
13543 fidl::encoding::Encode<
13544 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13545 fidl::encoding::DefaultFuchsiaResourceDialect,
13546 > for (T0,)
13547 {
13548 #[inline]
13549 unsafe fn encode(
13550 self,
13551 encoder: &mut fidl::encoding::Encoder<
13552 '_,
13553 fidl::encoding::DefaultFuchsiaResourceDialect,
13554 >,
13555 offset: usize,
13556 depth: fidl::encoding::Depth,
13557 ) -> fidl::Result<()> {
13558 encoder
13559 .debug_check_bounds::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(offset);
13560 // Zero out padding regions. There's no need to apply masks
13561 // because the unmasked parts will be overwritten by fields.
13562 // Write the fields.
13563 self.0.encode(encoder, offset + 0, depth)?;
13564 Ok(())
13565 }
13566 }
13567
13568 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13569 for BufferCollectionTokenGroupCreateChildrenSyncResponse
13570 {
13571 #[inline(always)]
13572 fn new_empty() -> Self {
13573 Self {
13574 tokens: fidl::new_empty!(
13575 fidl::encoding::Vector<
13576 fidl::encoding::Endpoint<
13577 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13578 >,
13579 64,
13580 >,
13581 fidl::encoding::DefaultFuchsiaResourceDialect
13582 ),
13583 }
13584 }
13585
13586 #[inline]
13587 unsafe fn decode(
13588 &mut self,
13589 decoder: &mut fidl::encoding::Decoder<
13590 '_,
13591 fidl::encoding::DefaultFuchsiaResourceDialect,
13592 >,
13593 offset: usize,
13594 _depth: fidl::encoding::Depth,
13595 ) -> fidl::Result<()> {
13596 decoder.debug_check_bounds::<Self>(offset);
13597 // Verify that padding bytes are zero.
13598 fidl::decode!(
13599 fidl::encoding::Vector<
13600 fidl::encoding::Endpoint<
13601 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13602 >,
13603 64,
13604 >,
13605 fidl::encoding::DefaultFuchsiaResourceDialect,
13606 &mut self.tokens,
13607 decoder,
13608 offset + 0,
13609 _depth
13610 )?;
13611 Ok(())
13612 }
13613 }
13614
13615 impl fidl::encoding::ResourceTypeMarker for BufferCollectionWaitForBuffersAllocatedResponse {
13616 type Borrowed<'a> = &'a mut Self;
13617 fn take_or_borrow<'a>(
13618 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13619 ) -> Self::Borrowed<'a> {
13620 value
13621 }
13622 }
13623
13624 unsafe impl fidl::encoding::TypeMarker for BufferCollectionWaitForBuffersAllocatedResponse {
13625 type Owned = Self;
13626
13627 #[inline(always)]
13628 fn inline_align(_context: fidl::encoding::Context) -> usize {
13629 8
13630 }
13631
13632 #[inline(always)]
13633 fn inline_size(_context: fidl::encoding::Context) -> usize {
13634 1304
13635 }
13636 }
13637
13638 unsafe impl
13639 fidl::encoding::Encode<
13640 BufferCollectionWaitForBuffersAllocatedResponse,
13641 fidl::encoding::DefaultFuchsiaResourceDialect,
13642 > for &mut BufferCollectionWaitForBuffersAllocatedResponse
13643 {
13644 #[inline]
13645 unsafe fn encode(
13646 self,
13647 encoder: &mut fidl::encoding::Encoder<
13648 '_,
13649 fidl::encoding::DefaultFuchsiaResourceDialect,
13650 >,
13651 offset: usize,
13652 _depth: fidl::encoding::Depth,
13653 ) -> fidl::Result<()> {
13654 encoder.debug_check_bounds::<BufferCollectionWaitForBuffersAllocatedResponse>(offset);
13655 // Delegate to tuple encoding.
13656 fidl::encoding::Encode::<
13657 BufferCollectionWaitForBuffersAllocatedResponse,
13658 fidl::encoding::DefaultFuchsiaResourceDialect,
13659 >::encode(
13660 (
13661 <i32 as fidl::encoding::ValueTypeMarker>::borrow(&self.status),
13662 <BufferCollectionInfo2 as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13663 &mut self.buffer_collection_info,
13664 ),
13665 ),
13666 encoder,
13667 offset,
13668 _depth,
13669 )
13670 }
13671 }
13672 unsafe impl<
13673 T0: fidl::encoding::Encode<i32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13674 T1: fidl::encoding::Encode<
13675 BufferCollectionInfo2,
13676 fidl::encoding::DefaultFuchsiaResourceDialect,
13677 >,
13678 >
13679 fidl::encoding::Encode<
13680 BufferCollectionWaitForBuffersAllocatedResponse,
13681 fidl::encoding::DefaultFuchsiaResourceDialect,
13682 > for (T0, T1)
13683 {
13684 #[inline]
13685 unsafe fn encode(
13686 self,
13687 encoder: &mut fidl::encoding::Encoder<
13688 '_,
13689 fidl::encoding::DefaultFuchsiaResourceDialect,
13690 >,
13691 offset: usize,
13692 depth: fidl::encoding::Depth,
13693 ) -> fidl::Result<()> {
13694 encoder.debug_check_bounds::<BufferCollectionWaitForBuffersAllocatedResponse>(offset);
13695 // Zero out padding regions. There's no need to apply masks
13696 // because the unmasked parts will be overwritten by fields.
13697 unsafe {
13698 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
13699 (ptr as *mut u64).write_unaligned(0);
13700 }
13701 // Write the fields.
13702 self.0.encode(encoder, offset + 0, depth)?;
13703 self.1.encode(encoder, offset + 8, depth)?;
13704 Ok(())
13705 }
13706 }
13707
13708 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13709 for BufferCollectionWaitForBuffersAllocatedResponse
13710 {
13711 #[inline(always)]
13712 fn new_empty() -> Self {
13713 Self {
13714 status: fidl::new_empty!(i32, fidl::encoding::DefaultFuchsiaResourceDialect),
13715 buffer_collection_info: fidl::new_empty!(
13716 BufferCollectionInfo2,
13717 fidl::encoding::DefaultFuchsiaResourceDialect
13718 ),
13719 }
13720 }
13721
13722 #[inline]
13723 unsafe fn decode(
13724 &mut self,
13725 decoder: &mut fidl::encoding::Decoder<
13726 '_,
13727 fidl::encoding::DefaultFuchsiaResourceDialect,
13728 >,
13729 offset: usize,
13730 _depth: fidl::encoding::Depth,
13731 ) -> fidl::Result<()> {
13732 decoder.debug_check_bounds::<Self>(offset);
13733 // Verify that padding bytes are zero.
13734 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
13735 let padval = unsafe { (ptr as *const u64).read_unaligned() };
13736 let mask = 0xffffffff00000000u64;
13737 let maskedval = padval & mask;
13738 if maskedval != 0 {
13739 return Err(fidl::Error::NonZeroPadding {
13740 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
13741 });
13742 }
13743 fidl::decode!(
13744 i32,
13745 fidl::encoding::DefaultFuchsiaResourceDialect,
13746 &mut self.status,
13747 decoder,
13748 offset + 0,
13749 _depth
13750 )?;
13751 fidl::decode!(
13752 BufferCollectionInfo2,
13753 fidl::encoding::DefaultFuchsiaResourceDialect,
13754 &mut self.buffer_collection_info,
13755 decoder,
13756 offset + 8,
13757 _depth
13758 )?;
13759 Ok(())
13760 }
13761 }
13762
13763 impl fidl::encoding::ResourceTypeMarker for NodeGetNodeRefResponse {
13764 type Borrowed<'a> = &'a mut Self;
13765 fn take_or_borrow<'a>(
13766 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13767 ) -> Self::Borrowed<'a> {
13768 value
13769 }
13770 }
13771
13772 unsafe impl fidl::encoding::TypeMarker for NodeGetNodeRefResponse {
13773 type Owned = Self;
13774
13775 #[inline(always)]
13776 fn inline_align(_context: fidl::encoding::Context) -> usize {
13777 4
13778 }
13779
13780 #[inline(always)]
13781 fn inline_size(_context: fidl::encoding::Context) -> usize {
13782 4
13783 }
13784 }
13785
13786 unsafe impl
13787 fidl::encoding::Encode<
13788 NodeGetNodeRefResponse,
13789 fidl::encoding::DefaultFuchsiaResourceDialect,
13790 > for &mut NodeGetNodeRefResponse
13791 {
13792 #[inline]
13793 unsafe fn encode(
13794 self,
13795 encoder: &mut fidl::encoding::Encoder<
13796 '_,
13797 fidl::encoding::DefaultFuchsiaResourceDialect,
13798 >,
13799 offset: usize,
13800 _depth: fidl::encoding::Depth,
13801 ) -> fidl::Result<()> {
13802 encoder.debug_check_bounds::<NodeGetNodeRefResponse>(offset);
13803 // Delegate to tuple encoding.
13804 fidl::encoding::Encode::<
13805 NodeGetNodeRefResponse,
13806 fidl::encoding::DefaultFuchsiaResourceDialect,
13807 >::encode(
13808 (<fidl::encoding::HandleType<
13809 fidl::Event,
13810 { fidl::ObjectType::EVENT.into_raw() },
13811 2147483648,
13812 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13813 &mut self.node_ref
13814 ),),
13815 encoder,
13816 offset,
13817 _depth,
13818 )
13819 }
13820 }
13821 unsafe impl<
13822 T0: fidl::encoding::Encode<
13823 fidl::encoding::HandleType<
13824 fidl::Event,
13825 { fidl::ObjectType::EVENT.into_raw() },
13826 2147483648,
13827 >,
13828 fidl::encoding::DefaultFuchsiaResourceDialect,
13829 >,
13830 >
13831 fidl::encoding::Encode<
13832 NodeGetNodeRefResponse,
13833 fidl::encoding::DefaultFuchsiaResourceDialect,
13834 > for (T0,)
13835 {
13836 #[inline]
13837 unsafe fn encode(
13838 self,
13839 encoder: &mut fidl::encoding::Encoder<
13840 '_,
13841 fidl::encoding::DefaultFuchsiaResourceDialect,
13842 >,
13843 offset: usize,
13844 depth: fidl::encoding::Depth,
13845 ) -> fidl::Result<()> {
13846 encoder.debug_check_bounds::<NodeGetNodeRefResponse>(offset);
13847 // Zero out padding regions. There's no need to apply masks
13848 // because the unmasked parts will be overwritten by fields.
13849 // Write the fields.
13850 self.0.encode(encoder, offset + 0, depth)?;
13851 Ok(())
13852 }
13853 }
13854
13855 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13856 for NodeGetNodeRefResponse
13857 {
13858 #[inline(always)]
13859 fn new_empty() -> Self {
13860 Self {
13861 node_ref: fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
13862 }
13863 }
13864
13865 #[inline]
13866 unsafe fn decode(
13867 &mut self,
13868 decoder: &mut fidl::encoding::Decoder<
13869 '_,
13870 fidl::encoding::DefaultFuchsiaResourceDialect,
13871 >,
13872 offset: usize,
13873 _depth: fidl::encoding::Depth,
13874 ) -> fidl::Result<()> {
13875 decoder.debug_check_bounds::<Self>(offset);
13876 // Verify that padding bytes are zero.
13877 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.node_ref, decoder, offset + 0, _depth)?;
13878 Ok(())
13879 }
13880 }
13881
13882 impl fidl::encoding::ResourceTypeMarker for NodeIsAlternateForRequest {
13883 type Borrowed<'a> = &'a mut Self;
13884 fn take_or_borrow<'a>(
13885 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13886 ) -> Self::Borrowed<'a> {
13887 value
13888 }
13889 }
13890
13891 unsafe impl fidl::encoding::TypeMarker for NodeIsAlternateForRequest {
13892 type Owned = Self;
13893
13894 #[inline(always)]
13895 fn inline_align(_context: fidl::encoding::Context) -> usize {
13896 4
13897 }
13898
13899 #[inline(always)]
13900 fn inline_size(_context: fidl::encoding::Context) -> usize {
13901 4
13902 }
13903 }
13904
13905 unsafe impl
13906 fidl::encoding::Encode<
13907 NodeIsAlternateForRequest,
13908 fidl::encoding::DefaultFuchsiaResourceDialect,
13909 > for &mut NodeIsAlternateForRequest
13910 {
13911 #[inline]
13912 unsafe fn encode(
13913 self,
13914 encoder: &mut fidl::encoding::Encoder<
13915 '_,
13916 fidl::encoding::DefaultFuchsiaResourceDialect,
13917 >,
13918 offset: usize,
13919 _depth: fidl::encoding::Depth,
13920 ) -> fidl::Result<()> {
13921 encoder.debug_check_bounds::<NodeIsAlternateForRequest>(offset);
13922 // Delegate to tuple encoding.
13923 fidl::encoding::Encode::<
13924 NodeIsAlternateForRequest,
13925 fidl::encoding::DefaultFuchsiaResourceDialect,
13926 >::encode(
13927 (<fidl::encoding::HandleType<
13928 fidl::Event,
13929 { fidl::ObjectType::EVENT.into_raw() },
13930 2147483648,
13931 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13932 &mut self.node_ref
13933 ),),
13934 encoder,
13935 offset,
13936 _depth,
13937 )
13938 }
13939 }
13940 unsafe impl<
13941 T0: fidl::encoding::Encode<
13942 fidl::encoding::HandleType<
13943 fidl::Event,
13944 { fidl::ObjectType::EVENT.into_raw() },
13945 2147483648,
13946 >,
13947 fidl::encoding::DefaultFuchsiaResourceDialect,
13948 >,
13949 >
13950 fidl::encoding::Encode<
13951 NodeIsAlternateForRequest,
13952 fidl::encoding::DefaultFuchsiaResourceDialect,
13953 > for (T0,)
13954 {
13955 #[inline]
13956 unsafe fn encode(
13957 self,
13958 encoder: &mut fidl::encoding::Encoder<
13959 '_,
13960 fidl::encoding::DefaultFuchsiaResourceDialect,
13961 >,
13962 offset: usize,
13963 depth: fidl::encoding::Depth,
13964 ) -> fidl::Result<()> {
13965 encoder.debug_check_bounds::<NodeIsAlternateForRequest>(offset);
13966 // Zero out padding regions. There's no need to apply masks
13967 // because the unmasked parts will be overwritten by fields.
13968 // Write the fields.
13969 self.0.encode(encoder, offset + 0, depth)?;
13970 Ok(())
13971 }
13972 }
13973
13974 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13975 for NodeIsAlternateForRequest
13976 {
13977 #[inline(always)]
13978 fn new_empty() -> Self {
13979 Self {
13980 node_ref: fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
13981 }
13982 }
13983
13984 #[inline]
13985 unsafe fn decode(
13986 &mut self,
13987 decoder: &mut fidl::encoding::Decoder<
13988 '_,
13989 fidl::encoding::DefaultFuchsiaResourceDialect,
13990 >,
13991 offset: usize,
13992 _depth: fidl::encoding::Depth,
13993 ) -> fidl::Result<()> {
13994 decoder.debug_check_bounds::<Self>(offset);
13995 // Verify that padding bytes are zero.
13996 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.node_ref, decoder, offset + 0, _depth)?;
13997 Ok(())
13998 }
13999 }
14000
14001 impl fidl::encoding::ResourceTypeMarker for SingleBufferInfo {
14002 type Borrowed<'a> = &'a mut Self;
14003 fn take_or_borrow<'a>(
14004 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14005 ) -> Self::Borrowed<'a> {
14006 value
14007 }
14008 }
14009
14010 unsafe impl fidl::encoding::TypeMarker for SingleBufferInfo {
14011 type Owned = Self;
14012
14013 #[inline(always)]
14014 fn inline_align(_context: fidl::encoding::Context) -> usize {
14015 8
14016 }
14017
14018 #[inline(always)]
14019 fn inline_size(_context: fidl::encoding::Context) -> usize {
14020 280
14021 }
14022 }
14023
14024 unsafe impl
14025 fidl::encoding::Encode<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
14026 for &mut SingleBufferInfo
14027 {
14028 #[inline]
14029 unsafe fn encode(
14030 self,
14031 encoder: &mut fidl::encoding::Encoder<
14032 '_,
14033 fidl::encoding::DefaultFuchsiaResourceDialect,
14034 >,
14035 offset: usize,
14036 _depth: fidl::encoding::Depth,
14037 ) -> fidl::Result<()> {
14038 encoder.debug_check_bounds::<SingleBufferInfo>(offset);
14039 // Delegate to tuple encoding.
14040 fidl::encoding::Encode::<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
14041 (
14042 <SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow(&self.settings),
14043 <VmoBuffer as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffer),
14044 ),
14045 encoder, offset, _depth
14046 )
14047 }
14048 }
14049 unsafe impl<
14050 T0: fidl::encoding::Encode<SingleBufferSettings, fidl::encoding::DefaultFuchsiaResourceDialect>,
14051 T1: fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>,
14052 > fidl::encoding::Encode<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
14053 for (T0, T1)
14054 {
14055 #[inline]
14056 unsafe fn encode(
14057 self,
14058 encoder: &mut fidl::encoding::Encoder<
14059 '_,
14060 fidl::encoding::DefaultFuchsiaResourceDialect,
14061 >,
14062 offset: usize,
14063 depth: fidl::encoding::Depth,
14064 ) -> fidl::Result<()> {
14065 encoder.debug_check_bounds::<SingleBufferInfo>(offset);
14066 // Zero out padding regions. There's no need to apply masks
14067 // because the unmasked parts will be overwritten by fields.
14068 // Write the fields.
14069 self.0.encode(encoder, offset + 0, depth)?;
14070 self.1.encode(encoder, offset + 264, depth)?;
14071 Ok(())
14072 }
14073 }
14074
14075 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14076 for SingleBufferInfo
14077 {
14078 #[inline(always)]
14079 fn new_empty() -> Self {
14080 Self {
14081 settings: fidl::new_empty!(
14082 SingleBufferSettings,
14083 fidl::encoding::DefaultFuchsiaResourceDialect
14084 ),
14085 buffer: fidl::new_empty!(VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect),
14086 }
14087 }
14088
14089 #[inline]
14090 unsafe fn decode(
14091 &mut self,
14092 decoder: &mut fidl::encoding::Decoder<
14093 '_,
14094 fidl::encoding::DefaultFuchsiaResourceDialect,
14095 >,
14096 offset: usize,
14097 _depth: fidl::encoding::Depth,
14098 ) -> fidl::Result<()> {
14099 decoder.debug_check_bounds::<Self>(offset);
14100 // Verify that padding bytes are zero.
14101 fidl::decode!(
14102 SingleBufferSettings,
14103 fidl::encoding::DefaultFuchsiaResourceDialect,
14104 &mut self.settings,
14105 decoder,
14106 offset + 0,
14107 _depth
14108 )?;
14109 fidl::decode!(
14110 VmoBuffer,
14111 fidl::encoding::DefaultFuchsiaResourceDialect,
14112 &mut self.buffer,
14113 decoder,
14114 offset + 264,
14115 _depth
14116 )?;
14117 Ok(())
14118 }
14119 }
14120
14121 impl fidl::encoding::ResourceTypeMarker for VmoBuffer {
14122 type Borrowed<'a> = &'a mut Self;
14123 fn take_or_borrow<'a>(
14124 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14125 ) -> Self::Borrowed<'a> {
14126 value
14127 }
14128 }
14129
14130 unsafe impl fidl::encoding::TypeMarker for VmoBuffer {
14131 type Owned = Self;
14132
14133 #[inline(always)]
14134 fn inline_align(_context: fidl::encoding::Context) -> usize {
14135 8
14136 }
14137
14138 #[inline(always)]
14139 fn inline_size(_context: fidl::encoding::Context) -> usize {
14140 16
14141 }
14142 }
14143
14144 unsafe impl fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>
14145 for &mut VmoBuffer
14146 {
14147 #[inline]
14148 unsafe fn encode(
14149 self,
14150 encoder: &mut fidl::encoding::Encoder<
14151 '_,
14152 fidl::encoding::DefaultFuchsiaResourceDialect,
14153 >,
14154 offset: usize,
14155 _depth: fidl::encoding::Depth,
14156 ) -> fidl::Result<()> {
14157 encoder.debug_check_bounds::<VmoBuffer>(offset);
14158 // Delegate to tuple encoding.
14159 fidl::encoding::Encode::<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
14160 (
14161 <fidl::encoding::Optional<fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.vmo),
14162 <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.vmo_usable_start),
14163 ),
14164 encoder, offset, _depth
14165 )
14166 }
14167 }
14168 unsafe impl<
14169 T0: fidl::encoding::Encode<
14170 fidl::encoding::Optional<
14171 fidl::encoding::HandleType<
14172 fidl::Vmo,
14173 { fidl::ObjectType::VMO.into_raw() },
14174 2147483648,
14175 >,
14176 >,
14177 fidl::encoding::DefaultFuchsiaResourceDialect,
14178 >,
14179 T1: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
14180 > fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>
14181 for (T0, T1)
14182 {
14183 #[inline]
14184 unsafe fn encode(
14185 self,
14186 encoder: &mut fidl::encoding::Encoder<
14187 '_,
14188 fidl::encoding::DefaultFuchsiaResourceDialect,
14189 >,
14190 offset: usize,
14191 depth: fidl::encoding::Depth,
14192 ) -> fidl::Result<()> {
14193 encoder.debug_check_bounds::<VmoBuffer>(offset);
14194 // Zero out padding regions. There's no need to apply masks
14195 // because the unmasked parts will be overwritten by fields.
14196 unsafe {
14197 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
14198 (ptr as *mut u64).write_unaligned(0);
14199 }
14200 // Write the fields.
14201 self.0.encode(encoder, offset + 0, depth)?;
14202 self.1.encode(encoder, offset + 8, depth)?;
14203 Ok(())
14204 }
14205 }
14206
14207 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect> for VmoBuffer {
14208 #[inline(always)]
14209 fn new_empty() -> Self {
14210 Self {
14211 vmo: fidl::new_empty!(
14212 fidl::encoding::Optional<
14213 fidl::encoding::HandleType<
14214 fidl::Vmo,
14215 { fidl::ObjectType::VMO.into_raw() },
14216 2147483648,
14217 >,
14218 >,
14219 fidl::encoding::DefaultFuchsiaResourceDialect
14220 ),
14221 vmo_usable_start: fidl::new_empty!(
14222 u64,
14223 fidl::encoding::DefaultFuchsiaResourceDialect
14224 ),
14225 }
14226 }
14227
14228 #[inline]
14229 unsafe fn decode(
14230 &mut self,
14231 decoder: &mut fidl::encoding::Decoder<
14232 '_,
14233 fidl::encoding::DefaultFuchsiaResourceDialect,
14234 >,
14235 offset: usize,
14236 _depth: fidl::encoding::Depth,
14237 ) -> fidl::Result<()> {
14238 decoder.debug_check_bounds::<Self>(offset);
14239 // Verify that padding bytes are zero.
14240 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
14241 let padval = unsafe { (ptr as *const u64).read_unaligned() };
14242 let mask = 0xffffffff00000000u64;
14243 let maskedval = padval & mask;
14244 if maskedval != 0 {
14245 return Err(fidl::Error::NonZeroPadding {
14246 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
14247 });
14248 }
14249 fidl::decode!(
14250 fidl::encoding::Optional<
14251 fidl::encoding::HandleType<
14252 fidl::Vmo,
14253 { fidl::ObjectType::VMO.into_raw() },
14254 2147483648,
14255 >,
14256 >,
14257 fidl::encoding::DefaultFuchsiaResourceDialect,
14258 &mut self.vmo,
14259 decoder,
14260 offset + 0,
14261 _depth
14262 )?;
14263 fidl::decode!(
14264 u64,
14265 fidl::encoding::DefaultFuchsiaResourceDialect,
14266 &mut self.vmo_usable_start,
14267 decoder,
14268 offset + 8,
14269 _depth
14270 )?;
14271 Ok(())
14272 }
14273 }
14274
14275 impl BufferCollectionTokenGroupCreateChildRequest {
14276 #[inline(always)]
14277 fn max_ordinal_present(&self) -> u64 {
14278 if let Some(_) = self.rights_attenuation_mask {
14279 return 2;
14280 }
14281 if let Some(_) = self.token_request {
14282 return 1;
14283 }
14284 0
14285 }
14286 }
14287
14288 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildRequest {
14289 type Borrowed<'a> = &'a mut Self;
14290 fn take_or_borrow<'a>(
14291 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14292 ) -> Self::Borrowed<'a> {
14293 value
14294 }
14295 }
14296
14297 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildRequest {
14298 type Owned = Self;
14299
14300 #[inline(always)]
14301 fn inline_align(_context: fidl::encoding::Context) -> usize {
14302 8
14303 }
14304
14305 #[inline(always)]
14306 fn inline_size(_context: fidl::encoding::Context) -> usize {
14307 16
14308 }
14309 }
14310
14311 unsafe impl
14312 fidl::encoding::Encode<
14313 BufferCollectionTokenGroupCreateChildRequest,
14314 fidl::encoding::DefaultFuchsiaResourceDialect,
14315 > for &mut BufferCollectionTokenGroupCreateChildRequest
14316 {
14317 unsafe fn encode(
14318 self,
14319 encoder: &mut fidl::encoding::Encoder<
14320 '_,
14321 fidl::encoding::DefaultFuchsiaResourceDialect,
14322 >,
14323 offset: usize,
14324 mut depth: fidl::encoding::Depth,
14325 ) -> fidl::Result<()> {
14326 encoder.debug_check_bounds::<BufferCollectionTokenGroupCreateChildRequest>(offset);
14327 // Vector header
14328 let max_ordinal: u64 = self.max_ordinal_present();
14329 encoder.write_num(max_ordinal, offset);
14330 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
14331 // Calling encoder.out_of_line_offset(0) is not allowed.
14332 if max_ordinal == 0 {
14333 return Ok(());
14334 }
14335 depth.increment()?;
14336 let envelope_size = 8;
14337 let bytes_len = max_ordinal as usize * envelope_size;
14338 #[allow(unused_variables)]
14339 let offset = encoder.out_of_line_offset(bytes_len);
14340 let mut _prev_end_offset: usize = 0;
14341 if 1 > max_ordinal {
14342 return Ok(());
14343 }
14344
14345 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
14346 // are envelope_size bytes.
14347 let cur_offset: usize = (1 - 1) * envelope_size;
14348
14349 // Zero reserved fields.
14350 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
14351
14352 // Safety:
14353 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
14354 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
14355 // envelope_size bytes, there is always sufficient room.
14356 fidl::encoding::encode_in_envelope_optional::<
14357 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
14358 fidl::encoding::DefaultFuchsiaResourceDialect,
14359 >(
14360 self.token_request.as_mut().map(
14361 <fidl::encoding::Endpoint<
14362 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14363 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
14364 ),
14365 encoder,
14366 offset + cur_offset,
14367 depth,
14368 )?;
14369
14370 _prev_end_offset = cur_offset + envelope_size;
14371 if 2 > max_ordinal {
14372 return Ok(());
14373 }
14374
14375 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
14376 // are envelope_size bytes.
14377 let cur_offset: usize = (2 - 1) * envelope_size;
14378
14379 // Zero reserved fields.
14380 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
14381
14382 // Safety:
14383 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
14384 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
14385 // envelope_size bytes, there is always sufficient room.
14386 fidl::encoding::encode_in_envelope_optional::<
14387 u32,
14388 fidl::encoding::DefaultFuchsiaResourceDialect,
14389 >(
14390 self.rights_attenuation_mask
14391 .as_ref()
14392 .map(<u32 as fidl::encoding::ValueTypeMarker>::borrow),
14393 encoder,
14394 offset + cur_offset,
14395 depth,
14396 )?;
14397
14398 _prev_end_offset = cur_offset + envelope_size;
14399
14400 Ok(())
14401 }
14402 }
14403
14404 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14405 for BufferCollectionTokenGroupCreateChildRequest
14406 {
14407 #[inline(always)]
14408 fn new_empty() -> Self {
14409 Self::default()
14410 }
14411
14412 unsafe fn decode(
14413 &mut self,
14414 decoder: &mut fidl::encoding::Decoder<
14415 '_,
14416 fidl::encoding::DefaultFuchsiaResourceDialect,
14417 >,
14418 offset: usize,
14419 mut depth: fidl::encoding::Depth,
14420 ) -> fidl::Result<()> {
14421 decoder.debug_check_bounds::<Self>(offset);
14422 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
14423 None => return Err(fidl::Error::NotNullable),
14424 Some(len) => len,
14425 };
14426 // Calling decoder.out_of_line_offset(0) is not allowed.
14427 if len == 0 {
14428 return Ok(());
14429 };
14430 depth.increment()?;
14431 let envelope_size = 8;
14432 let bytes_len = len * envelope_size;
14433 let offset = decoder.out_of_line_offset(bytes_len)?;
14434 // Decode the envelope for each type.
14435 let mut _next_ordinal_to_read = 0;
14436 let mut next_offset = offset;
14437 let end_offset = offset + bytes_len;
14438 _next_ordinal_to_read += 1;
14439 if next_offset >= end_offset {
14440 return Ok(());
14441 }
14442
14443 // Decode unknown envelopes for gaps in ordinals.
14444 while _next_ordinal_to_read < 1 {
14445 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14446 _next_ordinal_to_read += 1;
14447 next_offset += envelope_size;
14448 }
14449
14450 let next_out_of_line = decoder.next_out_of_line();
14451 let handles_before = decoder.remaining_handles();
14452 if let Some((inlined, num_bytes, num_handles)) =
14453 fidl::encoding::decode_envelope_header(decoder, next_offset)?
14454 {
14455 let member_inline_size = <fidl::encoding::Endpoint<
14456 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14457 > as fidl::encoding::TypeMarker>::inline_size(
14458 decoder.context
14459 );
14460 if inlined != (member_inline_size <= 4) {
14461 return Err(fidl::Error::InvalidInlineBitInEnvelope);
14462 }
14463 let inner_offset;
14464 let mut inner_depth = depth.clone();
14465 if inlined {
14466 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
14467 inner_offset = next_offset;
14468 } else {
14469 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
14470 inner_depth.increment()?;
14471 }
14472 let val_ref = self.token_request.get_or_insert_with(|| {
14473 fidl::new_empty!(
14474 fidl::encoding::Endpoint<
14475 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14476 >,
14477 fidl::encoding::DefaultFuchsiaResourceDialect
14478 )
14479 });
14480 fidl::decode!(
14481 fidl::encoding::Endpoint<
14482 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14483 >,
14484 fidl::encoding::DefaultFuchsiaResourceDialect,
14485 val_ref,
14486 decoder,
14487 inner_offset,
14488 inner_depth
14489 )?;
14490 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
14491 {
14492 return Err(fidl::Error::InvalidNumBytesInEnvelope);
14493 }
14494 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
14495 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
14496 }
14497 }
14498
14499 next_offset += envelope_size;
14500 _next_ordinal_to_read += 1;
14501 if next_offset >= end_offset {
14502 return Ok(());
14503 }
14504
14505 // Decode unknown envelopes for gaps in ordinals.
14506 while _next_ordinal_to_read < 2 {
14507 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14508 _next_ordinal_to_read += 1;
14509 next_offset += envelope_size;
14510 }
14511
14512 let next_out_of_line = decoder.next_out_of_line();
14513 let handles_before = decoder.remaining_handles();
14514 if let Some((inlined, num_bytes, num_handles)) =
14515 fidl::encoding::decode_envelope_header(decoder, next_offset)?
14516 {
14517 let member_inline_size =
14518 <u32 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
14519 if inlined != (member_inline_size <= 4) {
14520 return Err(fidl::Error::InvalidInlineBitInEnvelope);
14521 }
14522 let inner_offset;
14523 let mut inner_depth = depth.clone();
14524 if inlined {
14525 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
14526 inner_offset = next_offset;
14527 } else {
14528 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
14529 inner_depth.increment()?;
14530 }
14531 let val_ref = self.rights_attenuation_mask.get_or_insert_with(|| {
14532 fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect)
14533 });
14534 fidl::decode!(
14535 u32,
14536 fidl::encoding::DefaultFuchsiaResourceDialect,
14537 val_ref,
14538 decoder,
14539 inner_offset,
14540 inner_depth
14541 )?;
14542 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
14543 {
14544 return Err(fidl::Error::InvalidNumBytesInEnvelope);
14545 }
14546 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
14547 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
14548 }
14549 }
14550
14551 next_offset += envelope_size;
14552
14553 // Decode the remaining unknown envelopes.
14554 while next_offset < end_offset {
14555 _next_ordinal_to_read += 1;
14556 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14557 next_offset += envelope_size;
14558 }
14559
14560 Ok(())
14561 }
14562 }
14563}