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::NullableHandle {
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
1275 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
1276 self.inner.shutdown_with_epitaph(status)
1277 }
1278
1279 fn is_closed(&self) -> bool {
1280 self.inner.channel().is_closed()
1281 }
1282 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1283 self.inner.channel().on_closed()
1284 }
1285
1286 #[cfg(target_os = "fuchsia")]
1287 fn signal_peer(
1288 &self,
1289 clear_mask: zx::Signals,
1290 set_mask: zx::Signals,
1291 ) -> Result<(), zx_status::Status> {
1292 use fidl::Peered;
1293 self.inner.channel().signal_peer(clear_mask, set_mask)
1294 }
1295}
1296
1297impl AllocatorControlHandle {}
1298
1299#[must_use = "FIDL methods require a response to be sent"]
1300#[derive(Debug)]
1301pub struct AllocatorValidateBufferCollectionTokenResponder {
1302 control_handle: std::mem::ManuallyDrop<AllocatorControlHandle>,
1303 tx_id: u32,
1304}
1305
1306/// Set the the channel to be shutdown (see [`AllocatorControlHandle::shutdown`])
1307/// if the responder is dropped without sending a response, so that the client
1308/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1309impl std::ops::Drop for AllocatorValidateBufferCollectionTokenResponder {
1310 fn drop(&mut self) {
1311 self.control_handle.shutdown();
1312 // Safety: drops once, never accessed again
1313 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1314 }
1315}
1316
1317impl fidl::endpoints::Responder for AllocatorValidateBufferCollectionTokenResponder {
1318 type ControlHandle = AllocatorControlHandle;
1319
1320 fn control_handle(&self) -> &AllocatorControlHandle {
1321 &self.control_handle
1322 }
1323
1324 fn drop_without_shutdown(mut self) {
1325 // Safety: drops once, never accessed again due to mem::forget
1326 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1327 // Prevent Drop from running (which would shut down the channel)
1328 std::mem::forget(self);
1329 }
1330}
1331
1332impl AllocatorValidateBufferCollectionTokenResponder {
1333 /// Sends a response to the FIDL transaction.
1334 ///
1335 /// Sets the channel to shutdown if an error occurs.
1336 pub fn send(self, mut is_known: bool) -> Result<(), fidl::Error> {
1337 let _result = self.send_raw(is_known);
1338 if _result.is_err() {
1339 self.control_handle.shutdown();
1340 }
1341 self.drop_without_shutdown();
1342 _result
1343 }
1344
1345 /// Similar to "send" but does not shutdown the channel if an error occurs.
1346 pub fn send_no_shutdown_on_err(self, mut is_known: bool) -> Result<(), fidl::Error> {
1347 let _result = self.send_raw(is_known);
1348 self.drop_without_shutdown();
1349 _result
1350 }
1351
1352 fn send_raw(&self, mut is_known: bool) -> Result<(), fidl::Error> {
1353 self.control_handle.inner.send::<AllocatorValidateBufferCollectionTokenResponse>(
1354 (is_known,),
1355 self.tx_id,
1356 0x575b279b0236faea,
1357 fidl::encoding::DynamicFlags::empty(),
1358 )
1359 }
1360}
1361
1362#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1363pub struct BufferCollectionMarker;
1364
1365impl fidl::endpoints::ProtocolMarker for BufferCollectionMarker {
1366 type Proxy = BufferCollectionProxy;
1367 type RequestStream = BufferCollectionRequestStream;
1368 #[cfg(target_os = "fuchsia")]
1369 type SynchronousProxy = BufferCollectionSynchronousProxy;
1370
1371 const DEBUG_NAME: &'static str = "(anonymous) BufferCollection";
1372}
1373
1374pub trait BufferCollectionProxyInterface: Send + Sync {
1375 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
1376 fn r#sync(&self) -> Self::SyncResponseFut;
1377 fn r#close(&self) -> Result<(), fidl::Error>;
1378 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
1379 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
1380 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
1381 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
1382 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
1383 + Send;
1384 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
1385 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
1386 + Send;
1387 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
1388 fn r#set_constraints(
1389 &self,
1390 has_constraints: bool,
1391 constraints: &BufferCollectionConstraints,
1392 ) -> Result<(), fidl::Error>;
1393 type WaitForBuffersAllocatedResponseFut: std::future::Future<Output = Result<(i32, BufferCollectionInfo2), fidl::Error>>
1394 + Send;
1395 fn r#wait_for_buffers_allocated(&self) -> Self::WaitForBuffersAllocatedResponseFut;
1396 type CheckBuffersAllocatedResponseFut: std::future::Future<Output = Result<i32, fidl::Error>>
1397 + Send;
1398 fn r#check_buffers_allocated(&self) -> Self::CheckBuffersAllocatedResponseFut;
1399 fn r#attach_token(
1400 &self,
1401 rights_attenuation_mask: u32,
1402 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
1403 ) -> Result<(), fidl::Error>;
1404 fn r#attach_lifetime_tracking(
1405 &self,
1406 server_end: fidl::EventPair,
1407 buffers_remaining: u32,
1408 ) -> Result<(), fidl::Error>;
1409}
1410#[derive(Debug)]
1411#[cfg(target_os = "fuchsia")]
1412pub struct BufferCollectionSynchronousProxy {
1413 client: fidl::client::sync::Client,
1414}
1415
1416#[cfg(target_os = "fuchsia")]
1417impl fidl::endpoints::SynchronousProxy for BufferCollectionSynchronousProxy {
1418 type Proxy = BufferCollectionProxy;
1419 type Protocol = BufferCollectionMarker;
1420
1421 fn from_channel(inner: fidl::Channel) -> Self {
1422 Self::new(inner)
1423 }
1424
1425 fn into_channel(self) -> fidl::Channel {
1426 self.client.into_channel()
1427 }
1428
1429 fn as_channel(&self) -> &fidl::Channel {
1430 self.client.as_channel()
1431 }
1432}
1433
1434#[cfg(target_os = "fuchsia")]
1435impl BufferCollectionSynchronousProxy {
1436 pub fn new(channel: fidl::Channel) -> Self {
1437 let protocol_name = <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
1438 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
1439 }
1440
1441 pub fn into_channel(self) -> fidl::Channel {
1442 self.client.into_channel()
1443 }
1444
1445 /// Waits until an event arrives and returns it. It is safe for other
1446 /// threads to make concurrent requests while waiting for an event.
1447 pub fn wait_for_event(
1448 &self,
1449 deadline: zx::MonotonicInstant,
1450 ) -> Result<BufferCollectionEvent, fidl::Error> {
1451 BufferCollectionEvent::decode(self.client.wait_for_event(deadline)?)
1452 }
1453
1454 /// Ensure that previous messages, including Duplicate() messages on a
1455 /// token, collection, or group, have been received server side.
1456 ///
1457 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
1458 /// valid sysmem token risks the Sync() hanging forever. See
1459 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
1460 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
1461 /// Another way is to pass the token to BindSharedCollection(), which also
1462 /// validates the token as part of exchanging it for a BufferCollection
1463 /// channel, and BufferCollection Sync() can then be used.
1464 ///
1465 /// After a Sync(), it's then safe to send the client end of token_request
1466 /// to another participant knowing the server will recognize the token when
1467 /// it's sent into BindSharedCollection() by the other participant.
1468 ///
1469 /// Other options include waiting for each token.Duplicate() to complete
1470 /// individually (using separate call to token.Sync() after each), or
1471 /// calling Sync() on BufferCollection after the token has been turned in
1472 /// via BindSharedCollection().
1473 ///
1474 /// Another way to mitigate is to avoid calling Sync() on the token, and
1475 /// instead later deal with potential failure of BufferCollection.Sync() if
1476 /// the original token was invalid. This option can be preferable from a
1477 /// performance point of view, but requires client code to delay sending
1478 /// tokens duplicated from this token until after client code has converted
1479 /// the duplicating token to a BufferCollection and received successful
1480 /// response from BufferCollection.Sync().
1481 ///
1482 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
1483 /// When BufferCollection.Sync() isn't feasible, the caller must already
1484 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
1485 /// hang forever. See ValidateBufferCollectionToken() to check token
1486 /// validity first if the token isn't already known to be (is/was) valid.
1487 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
1488 let _response =
1489 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
1490 (),
1491 0x4577e238ae26291,
1492 fidl::encoding::DynamicFlags::empty(),
1493 ___deadline,
1494 )?;
1495 Ok(_response)
1496 }
1497
1498 /// On a BufferCollectionToken channel:
1499 ///
1500 /// Normally a participant will convert a BufferCollectionToken into a
1501 /// BufferCollection view, but a participant is also free to Close() the
1502 /// token (and then close the channel immediately or shortly later in
1503 /// response to server closing its end), which avoids causing logical buffer
1504 /// collection failure. Â Normally an unexpected token channel close will
1505 /// cause logical buffer collection failure (the only exceptions being
1506 /// certain cases involving AttachToken() or SetDispensable()).
1507 ///
1508 /// On a BufferCollection channel:
1509 ///
1510 /// By default the server handles unexpected failure of a BufferCollection
1511 /// by failing the whole logical buffer collection. Partly this is to
1512 /// expedite closing VMO handles to reclaim memory when any participant
1513 /// fails. If a participant would like to cleanly close a BufferCollection
1514 /// view without causing logical buffer collection failure, the participant
1515 /// can send Close() before closing the client end of the BufferCollection
1516 /// channel. If this is the last BufferCollection view, the logical buffer
1517 /// collection will still go away. The Close() can occur before or after
1518 /// SetConstraints(). If before SetConstraints(), the buffer collection
1519 /// won't require constraints from this node in order to allocate. If
1520 /// after SetConstraints(), the constraints are retained and aggregated
1521 /// along with any subsequent logical allocation(s), despite the lack of
1522 /// channel connection.
1523 ///
1524 /// On a BufferCollectionTokenGroup channel:
1525 ///
1526 /// By default, unexpected failure of a BufferCollectionTokenGroup will
1527 /// trigger failure of the logical BufferCollectionTokenGroup and will
1528 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
1529 /// channel without failing the logical group or propagating failure, send
1530 /// Close() before closing the channel client endpoint.
1531 ///
1532 /// If Close() occurs before AllChildrenPresent(), the logical buffer
1533 /// collection will still fail despite the Close() (because sysmem can't be
1534 /// sure whether all relevant children were created, so it's ambiguous
1535 /// whether all relevant constraints will be provided to sysmem). If
1536 /// Close() occurs after AllChildrenPresent(), the children and all their
1537 /// constraints remain intact (just as they would if the
1538 /// BufferCollectionTokenGroup channel had remained open), and the close
1539 /// doesn't trigger or propagate failure.
1540 pub fn r#close(&self) -> Result<(), fidl::Error> {
1541 self.client.send::<fidl::encoding::EmptyPayload>(
1542 (),
1543 0x5b1d7a4f5681fca7,
1544 fidl::encoding::DynamicFlags::empty(),
1545 )
1546 }
1547
1548 /// Set a name for VMOs in this buffer collection. The name may be truncated
1549 /// shorter. The name only affects VMOs allocated after it's set - this call
1550 /// does not rename existing VMOs. If multiple clients set different names
1551 /// then the larger priority value will win.
1552 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
1553 self.client.send::<NodeSetNameRequest>(
1554 (priority, name),
1555 0x77a41bb6217e2443,
1556 fidl::encoding::DynamicFlags::empty(),
1557 )
1558 }
1559
1560 /// Set information about the current client that can be used by sysmem to
1561 /// help debug leaking memory and hangs waiting for constraints. |name| can
1562 /// be an arbitrary string, but the current process name (see
1563 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
1564 /// arbitrary id, but the current process ID (see
1565 /// fsl::GetCurrentProcessKoid()) is a good default.
1566 ///
1567 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
1568 /// indicate which client is closing their channel first, leading to
1569 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
1570 /// over, but if happening earlier than expected, the
1571 /// client-channel-specific name can help diagnose where the failure is
1572 /// first coming from, from sysmem's point of view).
1573 ///
1574 /// By default (unless overriden by this message or using
1575 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
1576 /// parent Node at the time the child Node is created. While this can be
1577 /// better than nothing, it's often better for each participant to use
1578 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
1579 /// info directly relevant to the current client. Also, SetVerboseLogging()
1580 /// can be used to help disambiguate if a Node is suspected of having info
1581 /// that was copied from its parent.
1582 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
1583 self.client.send::<NodeSetDebugClientInfoRequest>(
1584 (name, id),
1585 0x7275759070eb5ee2,
1586 fidl::encoding::DynamicFlags::empty(),
1587 )
1588 }
1589
1590 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
1591 /// after creating a collection. Clients can call this method to change
1592 /// when the log is printed. If multiple client set the deadline, it's
1593 /// unspecified which deadline will take effect.
1594 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
1595 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
1596 (deadline,),
1597 0x46d38f4772638867,
1598 fidl::encoding::DynamicFlags::empty(),
1599 )
1600 }
1601
1602 /// Verbose logging includes constraints set via SetConstraints() from each
1603 /// client along with info set via SetDebugClientInfo() and the structure of
1604 /// the tree of Node(s).
1605 ///
1606 /// Normally sysmem prints only a single line complaint when aggregation
1607 /// fails, with just the specific detailed reason that aggregation failed,
1608 /// with minimal context. While this is often enough to diagnose a problem
1609 /// if only a small change was made and the system had been working before
1610 /// the small change, it's often not particularly helpful for getting a new
1611 /// buffer collection to work for the first time. Especially with more
1612 /// complex trees of nodes, involving things like AttachToken(),
1613 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
1614 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
1615 /// looks like and why it's failing a logical allocation, or why a tree or
1616 /// sub-tree is failing sooner than expected.
1617 ///
1618 /// The intent of the extra logging is to be acceptable from a performance
1619 /// point of view, if only enabled on a low number of buffer collections.
1620 /// If we're not tracking down a bug, we shouldn't send this message.
1621 ///
1622 /// If too many participants leave verbose logging enabled, we may end up
1623 /// needing to require that system-wide sysmem verbose logging be permitted
1624 /// via some other setting, to avoid sysmem spamming the log too much due to
1625 /// this message.
1626 ///
1627 /// This may be a NOP for some nodes due to intentional policy associated
1628 /// with the node, if we don't trust a node enough to let it turn on verbose
1629 /// logging.
1630 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
1631 self.client.send::<fidl::encoding::EmptyPayload>(
1632 (),
1633 0x6bfbe2cf1701d288,
1634 fidl::encoding::DynamicFlags::empty(),
1635 )
1636 }
1637
1638 /// This gets an event handle that can be used as a parameter to
1639 /// IsAlternateFor() called on any Node. The client will not be granted the
1640 /// right to signal this event, as this handle should only be used as proof
1641 /// that the client obtained this handle from this Node.
1642 ///
1643 /// Because this is a get not a set, no Sync() is needed between the
1644 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
1645 /// potentially being on different channels.
1646 ///
1647 /// See also IsAlternateFor().
1648 pub fn r#get_node_ref(
1649 &self,
1650 ___deadline: zx::MonotonicInstant,
1651 ) -> Result<fidl::Event, fidl::Error> {
1652 let _response =
1653 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
1654 (),
1655 0x467b7c75c35c3b84,
1656 fidl::encoding::DynamicFlags::empty(),
1657 ___deadline,
1658 )?;
1659 Ok(_response.node_ref)
1660 }
1661
1662 /// This checks whether the calling node is in a subtree rooted at a
1663 /// different child token of a common parent BufferCollectionTokenGroup, in
1664 /// relation to the passed-in node_ref.
1665 ///
1666 /// This call is for assisting with admission control de-duplication, and
1667 /// with debugging.
1668 ///
1669 /// The node_ref must be obtained using GetNodeRef() of a
1670 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
1671 ///
1672 /// The node_ref can be a duplicated handle; it's not necessary to call
1673 /// GetNodeRef() for every call to IsAlternateFor().
1674 ///
1675 /// If a calling token may not actually be a valid token at all due to
1676 /// a potentially hostile/untrusted provider of the token, call
1677 /// ValidateBufferCollectionToken() first instead of potentially getting
1678 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
1679 /// token not being a real token (not really talking to sysmem). Another
1680 /// option is to call BindSharedCollection with this token first which also
1681 /// validates the token along with converting it to a BufferCollection, then
1682 /// call BufferCollection IsAlternateFor().
1683 ///
1684 /// error values:
1685 ///
1686 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
1687 /// buffer collection as the calling Node. Before logical allocation and
1688 /// within the same logical allocation sub-tree, this essentially means that
1689 /// the node_ref was never part of this logical buffer collection, since
1690 /// before logical allocation all node_refs that come into existence remain
1691 /// in existence at least until logical allocation (including Node(s) that
1692 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
1693 /// to be returned, this Node's channel needs to still be connected server
1694 /// side, which won't be the case if the whole logical allocation has
1695 /// failed. After logical allocation or in a different logical allocation
1696 /// sub-tree there are additional potential reasons for this error. For
1697 /// example a different logical allocation (separated from this Node(s)
1698 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
1699 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
1700 /// exist and may select a different child sub-tree than the sub-tree the
1701 /// node_ref is in causing deletion of the node_ref Node. The only time
1702 /// sysmem keeps a Node around after that Node has no corresponding channel
1703 /// is when Close() is used and the Node's sub-tree has not yet failed.
1704 /// Another reason for this error is if the node_ref is an eventpair handle
1705 /// with sufficient rights, but isn't actually a real node_ref obtained from
1706 /// GetNodeRef().
1707 ///
1708 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
1709 /// eventpair handle, or doesn't have the needed rights expected on a real
1710 /// node_ref.
1711 ///
1712 /// No other failing status codes are returned by this call. However,
1713 /// sysmem may add additional codes in future, so the client should have
1714 /// sensible default handling for any failing status code.
1715 ///
1716 /// On success, is_alternate has the following meaning:
1717 /// * true - The first parent node in common between the calling node and
1718 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
1719 /// the calling Node and the node_ref Node will _not_ have both their
1720 /// constraints apply - rather sysmem will choose one or the other of
1721 /// the constraints - never both. This is because only one child of
1722 /// a BufferCollectionTokenGroup is selected during logical allocation,
1723 /// with only that one child's sub-tree contributing to constraints
1724 /// aggregation.
1725 /// * false - The first parent node in common between the calling Node and
1726 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
1727 /// this means the first parent node in common is a
1728 /// BufferCollectionToken or BufferCollection (regardless of not
1729 /// Close()ed or Close()ed). This means that the calling Node and the
1730 /// node_ref Node _may_ have both their constraints apply during
1731 /// constraints aggregation of the logical allocation, if both Node(s)
1732 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
1733 /// In this case, there is no BufferCollectionTokenGroup that will
1734 /// directly prevent the two Node(s) from both being selected and their
1735 /// constraints both aggregated, but even when false, one or both
1736 /// Node(s) may still be eliminated from consideration if one or both
1737 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
1738 /// which selects a child sub-tree other than the sub-tree containing
1739 /// the calling Node or node_ref Node.
1740 pub fn r#is_alternate_for(
1741 &self,
1742 mut node_ref: fidl::Event,
1743 ___deadline: zx::MonotonicInstant,
1744 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
1745 let _response = self.client.send_query::<
1746 NodeIsAlternateForRequest,
1747 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
1748 >(
1749 (node_ref,),
1750 0x33a2a7aff2776c07,
1751 fidl::encoding::DynamicFlags::empty(),
1752 ___deadline,
1753 )?;
1754 Ok(_response.map(|x| x.is_alternate))
1755 }
1756
1757 /// Provide BufferCollectionConstraints to the logical BufferCollection.
1758 ///
1759 /// A participant may only call SetConstraints() once.
1760 ///
1761 /// Sometimes the initiator is a participant only in the sense of wanting to
1762 /// keep an eye on success/failure to populate with buffers, and zx.Status
1763 /// on failure. In that case, `has_constraints` can be false, and
1764 /// `constraints` will be ignored.
1765 ///
1766 /// VMO handles will not be provided to the client that sends null
1767 /// constraints - that can be intentional for an initiator that doesn't need
1768 /// VMO handles. Not having VMO handles doesn't prevent the initator from
1769 /// adjusting which portion of a buffer is considered valid and similar, but
1770 /// the initiator can't hold a VMO handle open to prevent the logical
1771 /// BufferCollection from cleaning up if the logical BufferCollection needs
1772 /// to go away regardless of the initiator's degree of involvement for
1773 /// whatever reason.
1774 ///
1775 /// For population of buffers to be attempted, all holders of a
1776 /// BufferCollection client channel need to call SetConstraints() before
1777 /// sysmem will attempt to allocate buffers.
1778 ///
1779 /// `has_constraints` if false, the constraints are effectively null, and
1780 /// `constraints` are ignored. The sender of null constraints won't get any
1781 /// VMO handles in BufferCollectionInfo, but can still find out how many
1782 /// buffers were allocated and can still refer to buffers by their
1783 /// buffer_index.
1784 ///
1785 /// `constraints` are constraints on the buffer collection.
1786 pub fn r#set_constraints(
1787 &self,
1788 mut has_constraints: bool,
1789 mut constraints: &BufferCollectionConstraints,
1790 ) -> Result<(), fidl::Error> {
1791 self.client.send::<BufferCollectionSetConstraintsRequest>(
1792 (has_constraints, constraints),
1793 0x4d9c3406c213227b,
1794 fidl::encoding::DynamicFlags::empty(),
1795 )
1796 }
1797
1798 /// This request completes when buffers have been allocated, responds with
1799 /// some failure detail if allocation has been attempted but failed.
1800 ///
1801 /// The following must occur before buffers will be allocated:
1802 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
1803 /// must be turned in via BindSharedCollection().
1804 /// * All BufferCollection(s) of the logical BufferCollection must have
1805 /// had SetConstraints() sent to them.
1806 ///
1807 /// Returns `ZX_OK` if successful.
1808 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
1809 /// fulfilled due to resource exhaustion.
1810 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
1811 /// obtain the buffers it requested.
1812 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
1813 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
1814 /// satisfied, perhaps due to hardware limitations.
1815 ///
1816 /// `buffer_collection_info` has the VMO handles and other related info.
1817 pub fn r#wait_for_buffers_allocated(
1818 &self,
1819 ___deadline: zx::MonotonicInstant,
1820 ) -> Result<(i32, BufferCollectionInfo2), fidl::Error> {
1821 let _response = self.client.send_query::<
1822 fidl::encoding::EmptyPayload,
1823 BufferCollectionWaitForBuffersAllocatedResponse,
1824 >(
1825 (),
1826 0x714667ea2a29a3a2,
1827 fidl::encoding::DynamicFlags::empty(),
1828 ___deadline,
1829 )?;
1830 Ok((_response.status, _response.buffer_collection_info))
1831 }
1832
1833 /// This returns the same result code as WaitForBuffersAllocated if the
1834 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
1835 /// if WaitForBuffersAllocated would block.
1836 pub fn r#check_buffers_allocated(
1837 &self,
1838 ___deadline: zx::MonotonicInstant,
1839 ) -> Result<i32, fidl::Error> {
1840 let _response = self.client.send_query::<
1841 fidl::encoding::EmptyPayload,
1842 BufferCollectionCheckBuffersAllocatedResponse,
1843 >(
1844 (),
1845 0x245bb81f79189e9,
1846 fidl::encoding::DynamicFlags::empty(),
1847 ___deadline,
1848 )?;
1849 Ok(_response.status)
1850 }
1851
1852 /// Create a new token, for trying to add a new participant to an existing
1853 /// collection, if the existing collection's buffer counts, constraints,
1854 /// and participants allow.
1855 ///
1856 /// This can be useful in replacing a failed participant, and/or in
1857 /// adding/re-adding a participant after buffers have already been
1858 /// allocated.
1859 ///
1860 /// Failure of an attached token / collection does not propagate to the
1861 /// parent of the attached token. Failure does propagate from a normal
1862 /// child of a dispensable token to the dispensable token. Failure
1863 /// of a child is blocked from reaching its parent if the child is attached,
1864 /// or if the child is dispensable and the failure occurred after logical
1865 /// allocation.
1866 ///
1867 /// An initiator may in some scenarios choose to initially use a dispensable
1868 /// token for a given instance of a participant, and then later if the first
1869 /// instance of that participant fails, a new second instance of that
1870 /// participant my be given a token created with AttachToken().
1871 ///
1872 /// From the point of view of the client end of the BufferCollectionToken
1873 /// channel, the token acts like any other token. The client can
1874 /// Duplicate() the token as needed, and can send the token to a different
1875 /// process. The token should be converted to a BufferCollection channel
1876 /// as normal by calling BindSharedCollection(). SetConstraints() should
1877 /// be called on that BufferCollection channel.
1878 ///
1879 /// A success result from WaitForBuffersAllocated() means the new
1880 /// participant's constraints were satisfiable using the already-existing
1881 /// buffer collection, the already-established BufferCollectionInfo
1882 /// including image format constraints, and the already-existing other
1883 /// participants and their buffer counts. A failure result means the new
1884 /// participant's constraints cannot be satisfied using the existing
1885 /// buffer collection and its already-logically-allocated participants.
1886 /// Creating a new collection instead may allow all participant's
1887 /// constraints to be satisfied, assuming SetDispensable() is used in place
1888 /// of AttachToken(), or a normal token is used.
1889 ///
1890 /// A token created with AttachToken() performs constraints aggregation with
1891 /// all constraints currently in effect on the buffer collection, plus the
1892 /// attached token under consideration plus child tokens under the attached
1893 /// token which are not themselves an attached token or under such a token.
1894 ///
1895 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
1896 /// first-come first-served, but a child can't logically allocate before
1897 /// all its parents have sent SetConstraints().
1898 ///
1899 /// See also SetDispensable(), which in contrast to AttachToken(), has the
1900 /// created token + children participate in constraints aggregation along
1901 /// with its parent.
1902 ///
1903 /// The newly created token needs to be Sync()ed to sysmem before the new
1904 /// token can be passed to BindSharedCollection(). The Sync() of the new
1905 /// token can be accomplished with BufferCollection.Sync() on this
1906 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
1907 /// token also works. A BufferCollectionToken.Sync() can be started after
1908 /// any BufferCollectionToken.Duplicate() messages have been sent via the
1909 /// newly created token, to also sync those additional tokens to sysmem
1910 /// using a single round-trip.
1911 ///
1912 /// These values for rights_attenuation_mask result in no attenuation (note
1913 /// that 0 is not on this list; 0 will output an ERROR to the system log
1914 /// to help diagnose the bug in client code):
1915 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
1916 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
1917 pub fn r#attach_token(
1918 &self,
1919 mut rights_attenuation_mask: u32,
1920 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
1921 ) -> Result<(), fidl::Error> {
1922 self.client.send::<BufferCollectionAttachTokenRequest>(
1923 (rights_attenuation_mask, token_request),
1924 0x6f5adcca4ac7443e,
1925 fidl::encoding::DynamicFlags::empty(),
1926 )
1927 }
1928
1929 /// AttachLifetimeTracking:
1930 ///
1931 /// AttachLifetimeTracking() is intended to allow a client to wait until an
1932 /// old logical buffer collection is fully or mostly deallocated before
1933 /// attempting allocation of a new logical buffer collection.
1934 ///
1935 /// Attach an eventpair endpoint to the logical buffer collection, so that
1936 /// the server_end will be closed when the number of buffers allocated
1937 /// drops to 'buffers_remaining'. The server_end won't close until after
1938 /// logical allocation has completed.
1939 ///
1940 /// If logical allocation fails, such as for an attached sub-tree (using
1941 /// AttachToken()), the server_end will close during that failure regardless
1942 /// of the number of buffers potenitally allocated in the overall logical
1943 /// buffer collection.
1944 ///
1945 /// The lifetime signalled by this event includes asynchronous cleanup of
1946 /// allocated buffers, and this asynchronous cleanup cannot occur until all
1947 /// holders of VMO handles to the buffers have closed those VMO handles.
1948 /// Therefore clients should take care not to become blocked forever waiting
1949 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
1950 /// participants using the logical buffer collection are less trusted or
1951 /// less reliable.
1952 ///
1953 /// The buffers_remaining parameter allows waiting for all but
1954 /// buffers_remaining buffers to be fully deallocated. This can be useful
1955 /// in situations where a known number of buffers are intentionally not
1956 /// closed so that the data can continue to be used, such as for keeping the
1957 /// last available video picture displayed in the UI even if the video
1958 /// stream was using protected output buffers. It's outside the scope of
1959 /// the BufferCollection interface (at least for now) to determine how many
1960 /// buffers may be held without closing, but it'll typically be in the range
1961 /// 0-2.
1962 ///
1963 /// This mechanism is meant to be compatible with other protocols providing
1964 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
1965 /// same event can be sent to more than one AttachLifetimeTracking(), and
1966 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
1967 /// over conditions are met (all holders of duplicates have closed their
1968 /// handle(s)).
1969 ///
1970 /// There is no way to cancel an attach. Closing the client end of the
1971 /// eventpair doesn't subtract from the number of pending attach(es).
1972 ///
1973 /// Closing the client's end doesn't result in any action by the server.
1974 /// If the server listens to events from the client end at all, it is for
1975 /// debug logging only.
1976 ///
1977 /// The server intentionally doesn't "trust" any bits signalled by the
1978 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
1979 /// which can't be triggered early, and is only triggered when all handles
1980 /// to server_end are closed. No meaning is associated with any of the
1981 /// other signal bits, and clients should functionally ignore any other
1982 /// signal bits on either end of the eventpair or its peer.
1983 ///
1984 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
1985 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
1986 /// transfer without causing CodecFactory channel failure).
1987 pub fn r#attach_lifetime_tracking(
1988 &self,
1989 mut server_end: fidl::EventPair,
1990 mut buffers_remaining: u32,
1991 ) -> Result<(), fidl::Error> {
1992 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
1993 (server_end, buffers_remaining),
1994 0x170d0f1d89d50989,
1995 fidl::encoding::DynamicFlags::empty(),
1996 )
1997 }
1998}
1999
2000#[cfg(target_os = "fuchsia")]
2001impl From<BufferCollectionSynchronousProxy> for zx::NullableHandle {
2002 fn from(value: BufferCollectionSynchronousProxy) -> Self {
2003 value.into_channel().into()
2004 }
2005}
2006
2007#[cfg(target_os = "fuchsia")]
2008impl From<fidl::Channel> for BufferCollectionSynchronousProxy {
2009 fn from(value: fidl::Channel) -> Self {
2010 Self::new(value)
2011 }
2012}
2013
2014#[cfg(target_os = "fuchsia")]
2015impl fidl::endpoints::FromClient for BufferCollectionSynchronousProxy {
2016 type Protocol = BufferCollectionMarker;
2017
2018 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionMarker>) -> Self {
2019 Self::new(value.into_channel())
2020 }
2021}
2022
2023#[derive(Debug, Clone)]
2024pub struct BufferCollectionProxy {
2025 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
2026}
2027
2028impl fidl::endpoints::Proxy for BufferCollectionProxy {
2029 type Protocol = BufferCollectionMarker;
2030
2031 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
2032 Self::new(inner)
2033 }
2034
2035 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
2036 self.client.into_channel().map_err(|client| Self { client })
2037 }
2038
2039 fn as_channel(&self) -> &::fidl::AsyncChannel {
2040 self.client.as_channel()
2041 }
2042}
2043
2044impl BufferCollectionProxy {
2045 /// Create a new Proxy for fuchsia.sysmem/BufferCollection.
2046 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
2047 let protocol_name = <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
2048 Self { client: fidl::client::Client::new(channel, protocol_name) }
2049 }
2050
2051 /// Get a Stream of events from the remote end of the protocol.
2052 ///
2053 /// # Panics
2054 ///
2055 /// Panics if the event stream was already taken.
2056 pub fn take_event_stream(&self) -> BufferCollectionEventStream {
2057 BufferCollectionEventStream { event_receiver: self.client.take_event_receiver() }
2058 }
2059
2060 /// Ensure that previous messages, including Duplicate() messages on a
2061 /// token, collection, or group, have been received server side.
2062 ///
2063 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
2064 /// valid sysmem token risks the Sync() hanging forever. See
2065 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
2066 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
2067 /// Another way is to pass the token to BindSharedCollection(), which also
2068 /// validates the token as part of exchanging it for a BufferCollection
2069 /// channel, and BufferCollection Sync() can then be used.
2070 ///
2071 /// After a Sync(), it's then safe to send the client end of token_request
2072 /// to another participant knowing the server will recognize the token when
2073 /// it's sent into BindSharedCollection() by the other participant.
2074 ///
2075 /// Other options include waiting for each token.Duplicate() to complete
2076 /// individually (using separate call to token.Sync() after each), or
2077 /// calling Sync() on BufferCollection after the token has been turned in
2078 /// via BindSharedCollection().
2079 ///
2080 /// Another way to mitigate is to avoid calling Sync() on the token, and
2081 /// instead later deal with potential failure of BufferCollection.Sync() if
2082 /// the original token was invalid. This option can be preferable from a
2083 /// performance point of view, but requires client code to delay sending
2084 /// tokens duplicated from this token until after client code has converted
2085 /// the duplicating token to a BufferCollection and received successful
2086 /// response from BufferCollection.Sync().
2087 ///
2088 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
2089 /// When BufferCollection.Sync() isn't feasible, the caller must already
2090 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
2091 /// hang forever. See ValidateBufferCollectionToken() to check token
2092 /// validity first if the token isn't already known to be (is/was) valid.
2093 pub fn r#sync(
2094 &self,
2095 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
2096 BufferCollectionProxyInterface::r#sync(self)
2097 }
2098
2099 /// On a BufferCollectionToken channel:
2100 ///
2101 /// Normally a participant will convert a BufferCollectionToken into a
2102 /// BufferCollection view, but a participant is also free to Close() the
2103 /// token (and then close the channel immediately or shortly later in
2104 /// response to server closing its end), which avoids causing logical buffer
2105 /// collection failure. Â Normally an unexpected token channel close will
2106 /// cause logical buffer collection failure (the only exceptions being
2107 /// certain cases involving AttachToken() or SetDispensable()).
2108 ///
2109 /// On a BufferCollection channel:
2110 ///
2111 /// By default the server handles unexpected failure of a BufferCollection
2112 /// by failing the whole logical buffer collection. Partly this is to
2113 /// expedite closing VMO handles to reclaim memory when any participant
2114 /// fails. If a participant would like to cleanly close a BufferCollection
2115 /// view without causing logical buffer collection failure, the participant
2116 /// can send Close() before closing the client end of the BufferCollection
2117 /// channel. If this is the last BufferCollection view, the logical buffer
2118 /// collection will still go away. The Close() can occur before or after
2119 /// SetConstraints(). If before SetConstraints(), the buffer collection
2120 /// won't require constraints from this node in order to allocate. If
2121 /// after SetConstraints(), the constraints are retained and aggregated
2122 /// along with any subsequent logical allocation(s), despite the lack of
2123 /// channel connection.
2124 ///
2125 /// On a BufferCollectionTokenGroup channel:
2126 ///
2127 /// By default, unexpected failure of a BufferCollectionTokenGroup will
2128 /// trigger failure of the logical BufferCollectionTokenGroup and will
2129 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
2130 /// channel without failing the logical group or propagating failure, send
2131 /// Close() before closing the channel client endpoint.
2132 ///
2133 /// If Close() occurs before AllChildrenPresent(), the logical buffer
2134 /// collection will still fail despite the Close() (because sysmem can't be
2135 /// sure whether all relevant children were created, so it's ambiguous
2136 /// whether all relevant constraints will be provided to sysmem). If
2137 /// Close() occurs after AllChildrenPresent(), the children and all their
2138 /// constraints remain intact (just as they would if the
2139 /// BufferCollectionTokenGroup channel had remained open), and the close
2140 /// doesn't trigger or propagate failure.
2141 pub fn r#close(&self) -> Result<(), fidl::Error> {
2142 BufferCollectionProxyInterface::r#close(self)
2143 }
2144
2145 /// Set a name for VMOs in this buffer collection. The name may be truncated
2146 /// shorter. The name only affects VMOs allocated after it's set - this call
2147 /// does not rename existing VMOs. If multiple clients set different names
2148 /// then the larger priority value will win.
2149 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
2150 BufferCollectionProxyInterface::r#set_name(self, priority, name)
2151 }
2152
2153 /// Set information about the current client that can be used by sysmem to
2154 /// help debug leaking memory and hangs waiting for constraints. |name| can
2155 /// be an arbitrary string, but the current process name (see
2156 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
2157 /// arbitrary id, but the current process ID (see
2158 /// fsl::GetCurrentProcessKoid()) is a good default.
2159 ///
2160 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
2161 /// indicate which client is closing their channel first, leading to
2162 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
2163 /// over, but if happening earlier than expected, the
2164 /// client-channel-specific name can help diagnose where the failure is
2165 /// first coming from, from sysmem's point of view).
2166 ///
2167 /// By default (unless overriden by this message or using
2168 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
2169 /// parent Node at the time the child Node is created. While this can be
2170 /// better than nothing, it's often better for each participant to use
2171 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
2172 /// info directly relevant to the current client. Also, SetVerboseLogging()
2173 /// can be used to help disambiguate if a Node is suspected of having info
2174 /// that was copied from its parent.
2175 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
2176 BufferCollectionProxyInterface::r#set_debug_client_info(self, name, id)
2177 }
2178
2179 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
2180 /// after creating a collection. Clients can call this method to change
2181 /// when the log is printed. If multiple client set the deadline, it's
2182 /// unspecified which deadline will take effect.
2183 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
2184 BufferCollectionProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
2185 }
2186
2187 /// Verbose logging includes constraints set via SetConstraints() from each
2188 /// client along with info set via SetDebugClientInfo() and the structure of
2189 /// the tree of Node(s).
2190 ///
2191 /// Normally sysmem prints only a single line complaint when aggregation
2192 /// fails, with just the specific detailed reason that aggregation failed,
2193 /// with minimal context. While this is often enough to diagnose a problem
2194 /// if only a small change was made and the system had been working before
2195 /// the small change, it's often not particularly helpful for getting a new
2196 /// buffer collection to work for the first time. Especially with more
2197 /// complex trees of nodes, involving things like AttachToken(),
2198 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
2199 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
2200 /// looks like and why it's failing a logical allocation, or why a tree or
2201 /// sub-tree is failing sooner than expected.
2202 ///
2203 /// The intent of the extra logging is to be acceptable from a performance
2204 /// point of view, if only enabled on a low number of buffer collections.
2205 /// If we're not tracking down a bug, we shouldn't send this message.
2206 ///
2207 /// If too many participants leave verbose logging enabled, we may end up
2208 /// needing to require that system-wide sysmem verbose logging be permitted
2209 /// via some other setting, to avoid sysmem spamming the log too much due to
2210 /// this message.
2211 ///
2212 /// This may be a NOP for some nodes due to intentional policy associated
2213 /// with the node, if we don't trust a node enough to let it turn on verbose
2214 /// logging.
2215 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
2216 BufferCollectionProxyInterface::r#set_verbose_logging(self)
2217 }
2218
2219 /// This gets an event handle that can be used as a parameter to
2220 /// IsAlternateFor() called on any Node. The client will not be granted the
2221 /// right to signal this event, as this handle should only be used as proof
2222 /// that the client obtained this handle from this Node.
2223 ///
2224 /// Because this is a get not a set, no Sync() is needed between the
2225 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
2226 /// potentially being on different channels.
2227 ///
2228 /// See also IsAlternateFor().
2229 pub fn r#get_node_ref(
2230 &self,
2231 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
2232 {
2233 BufferCollectionProxyInterface::r#get_node_ref(self)
2234 }
2235
2236 /// This checks whether the calling node is in a subtree rooted at a
2237 /// different child token of a common parent BufferCollectionTokenGroup, in
2238 /// relation to the passed-in node_ref.
2239 ///
2240 /// This call is for assisting with admission control de-duplication, and
2241 /// with debugging.
2242 ///
2243 /// The node_ref must be obtained using GetNodeRef() of a
2244 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
2245 ///
2246 /// The node_ref can be a duplicated handle; it's not necessary to call
2247 /// GetNodeRef() for every call to IsAlternateFor().
2248 ///
2249 /// If a calling token may not actually be a valid token at all due to
2250 /// a potentially hostile/untrusted provider of the token, call
2251 /// ValidateBufferCollectionToken() first instead of potentially getting
2252 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
2253 /// token not being a real token (not really talking to sysmem). Another
2254 /// option is to call BindSharedCollection with this token first which also
2255 /// validates the token along with converting it to a BufferCollection, then
2256 /// call BufferCollection IsAlternateFor().
2257 ///
2258 /// error values:
2259 ///
2260 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
2261 /// buffer collection as the calling Node. Before logical allocation and
2262 /// within the same logical allocation sub-tree, this essentially means that
2263 /// the node_ref was never part of this logical buffer collection, since
2264 /// before logical allocation all node_refs that come into existence remain
2265 /// in existence at least until logical allocation (including Node(s) that
2266 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
2267 /// to be returned, this Node's channel needs to still be connected server
2268 /// side, which won't be the case if the whole logical allocation has
2269 /// failed. After logical allocation or in a different logical allocation
2270 /// sub-tree there are additional potential reasons for this error. For
2271 /// example a different logical allocation (separated from this Node(s)
2272 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
2273 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
2274 /// exist and may select a different child sub-tree than the sub-tree the
2275 /// node_ref is in causing deletion of the node_ref Node. The only time
2276 /// sysmem keeps a Node around after that Node has no corresponding channel
2277 /// is when Close() is used and the Node's sub-tree has not yet failed.
2278 /// Another reason for this error is if the node_ref is an eventpair handle
2279 /// with sufficient rights, but isn't actually a real node_ref obtained from
2280 /// GetNodeRef().
2281 ///
2282 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
2283 /// eventpair handle, or doesn't have the needed rights expected on a real
2284 /// node_ref.
2285 ///
2286 /// No other failing status codes are returned by this call. However,
2287 /// sysmem may add additional codes in future, so the client should have
2288 /// sensible default handling for any failing status code.
2289 ///
2290 /// On success, is_alternate has the following meaning:
2291 /// * true - The first parent node in common between the calling node and
2292 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
2293 /// the calling Node and the node_ref Node will _not_ have both their
2294 /// constraints apply - rather sysmem will choose one or the other of
2295 /// the constraints - never both. This is because only one child of
2296 /// a BufferCollectionTokenGroup is selected during logical allocation,
2297 /// with only that one child's sub-tree contributing to constraints
2298 /// aggregation.
2299 /// * false - The first parent node in common between the calling Node and
2300 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
2301 /// this means the first parent node in common is a
2302 /// BufferCollectionToken or BufferCollection (regardless of not
2303 /// Close()ed or Close()ed). This means that the calling Node and the
2304 /// node_ref Node _may_ have both their constraints apply during
2305 /// constraints aggregation of the logical allocation, if both Node(s)
2306 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
2307 /// In this case, there is no BufferCollectionTokenGroup that will
2308 /// directly prevent the two Node(s) from both being selected and their
2309 /// constraints both aggregated, but even when false, one or both
2310 /// Node(s) may still be eliminated from consideration if one or both
2311 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
2312 /// which selects a child sub-tree other than the sub-tree containing
2313 /// the calling Node or node_ref Node.
2314 pub fn r#is_alternate_for(
2315 &self,
2316 mut node_ref: fidl::Event,
2317 ) -> fidl::client::QueryResponseFut<
2318 NodeIsAlternateForResult,
2319 fidl::encoding::DefaultFuchsiaResourceDialect,
2320 > {
2321 BufferCollectionProxyInterface::r#is_alternate_for(self, node_ref)
2322 }
2323
2324 /// Provide BufferCollectionConstraints to the logical BufferCollection.
2325 ///
2326 /// A participant may only call SetConstraints() once.
2327 ///
2328 /// Sometimes the initiator is a participant only in the sense of wanting to
2329 /// keep an eye on success/failure to populate with buffers, and zx.Status
2330 /// on failure. In that case, `has_constraints` can be false, and
2331 /// `constraints` will be ignored.
2332 ///
2333 /// VMO handles will not be provided to the client that sends null
2334 /// constraints - that can be intentional for an initiator that doesn't need
2335 /// VMO handles. Not having VMO handles doesn't prevent the initator from
2336 /// adjusting which portion of a buffer is considered valid and similar, but
2337 /// the initiator can't hold a VMO handle open to prevent the logical
2338 /// BufferCollection from cleaning up if the logical BufferCollection needs
2339 /// to go away regardless of the initiator's degree of involvement for
2340 /// whatever reason.
2341 ///
2342 /// For population of buffers to be attempted, all holders of a
2343 /// BufferCollection client channel need to call SetConstraints() before
2344 /// sysmem will attempt to allocate buffers.
2345 ///
2346 /// `has_constraints` if false, the constraints are effectively null, and
2347 /// `constraints` are ignored. The sender of null constraints won't get any
2348 /// VMO handles in BufferCollectionInfo, but can still find out how many
2349 /// buffers were allocated and can still refer to buffers by their
2350 /// buffer_index.
2351 ///
2352 /// `constraints` are constraints on the buffer collection.
2353 pub fn r#set_constraints(
2354 &self,
2355 mut has_constraints: bool,
2356 mut constraints: &BufferCollectionConstraints,
2357 ) -> Result<(), fidl::Error> {
2358 BufferCollectionProxyInterface::r#set_constraints(self, has_constraints, constraints)
2359 }
2360
2361 /// This request completes when buffers have been allocated, responds with
2362 /// some failure detail if allocation has been attempted but failed.
2363 ///
2364 /// The following must occur before buffers will be allocated:
2365 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
2366 /// must be turned in via BindSharedCollection().
2367 /// * All BufferCollection(s) of the logical BufferCollection must have
2368 /// had SetConstraints() sent to them.
2369 ///
2370 /// Returns `ZX_OK` if successful.
2371 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
2372 /// fulfilled due to resource exhaustion.
2373 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
2374 /// obtain the buffers it requested.
2375 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
2376 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
2377 /// satisfied, perhaps due to hardware limitations.
2378 ///
2379 /// `buffer_collection_info` has the VMO handles and other related info.
2380 pub fn r#wait_for_buffers_allocated(
2381 &self,
2382 ) -> fidl::client::QueryResponseFut<
2383 (i32, BufferCollectionInfo2),
2384 fidl::encoding::DefaultFuchsiaResourceDialect,
2385 > {
2386 BufferCollectionProxyInterface::r#wait_for_buffers_allocated(self)
2387 }
2388
2389 /// This returns the same result code as WaitForBuffersAllocated if the
2390 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
2391 /// if WaitForBuffersAllocated would block.
2392 pub fn r#check_buffers_allocated(
2393 &self,
2394 ) -> fidl::client::QueryResponseFut<i32, fidl::encoding::DefaultFuchsiaResourceDialect> {
2395 BufferCollectionProxyInterface::r#check_buffers_allocated(self)
2396 }
2397
2398 /// Create a new token, for trying to add a new participant to an existing
2399 /// collection, if the existing collection's buffer counts, constraints,
2400 /// and participants allow.
2401 ///
2402 /// This can be useful in replacing a failed participant, and/or in
2403 /// adding/re-adding a participant after buffers have already been
2404 /// allocated.
2405 ///
2406 /// Failure of an attached token / collection does not propagate to the
2407 /// parent of the attached token. Failure does propagate from a normal
2408 /// child of a dispensable token to the dispensable token. Failure
2409 /// of a child is blocked from reaching its parent if the child is attached,
2410 /// or if the child is dispensable and the failure occurred after logical
2411 /// allocation.
2412 ///
2413 /// An initiator may in some scenarios choose to initially use a dispensable
2414 /// token for a given instance of a participant, and then later if the first
2415 /// instance of that participant fails, a new second instance of that
2416 /// participant my be given a token created with AttachToken().
2417 ///
2418 /// From the point of view of the client end of the BufferCollectionToken
2419 /// channel, the token acts like any other token. The client can
2420 /// Duplicate() the token as needed, and can send the token to a different
2421 /// process. The token should be converted to a BufferCollection channel
2422 /// as normal by calling BindSharedCollection(). SetConstraints() should
2423 /// be called on that BufferCollection channel.
2424 ///
2425 /// A success result from WaitForBuffersAllocated() means the new
2426 /// participant's constraints were satisfiable using the already-existing
2427 /// buffer collection, the already-established BufferCollectionInfo
2428 /// including image format constraints, and the already-existing other
2429 /// participants and their buffer counts. A failure result means the new
2430 /// participant's constraints cannot be satisfied using the existing
2431 /// buffer collection and its already-logically-allocated participants.
2432 /// Creating a new collection instead may allow all participant's
2433 /// constraints to be satisfied, assuming SetDispensable() is used in place
2434 /// of AttachToken(), or a normal token is used.
2435 ///
2436 /// A token created with AttachToken() performs constraints aggregation with
2437 /// all constraints currently in effect on the buffer collection, plus the
2438 /// attached token under consideration plus child tokens under the attached
2439 /// token which are not themselves an attached token or under such a token.
2440 ///
2441 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
2442 /// first-come first-served, but a child can't logically allocate before
2443 /// all its parents have sent SetConstraints().
2444 ///
2445 /// See also SetDispensable(), which in contrast to AttachToken(), has the
2446 /// created token + children participate in constraints aggregation along
2447 /// with its parent.
2448 ///
2449 /// The newly created token needs to be Sync()ed to sysmem before the new
2450 /// token can be passed to BindSharedCollection(). The Sync() of the new
2451 /// token can be accomplished with BufferCollection.Sync() on this
2452 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
2453 /// token also works. A BufferCollectionToken.Sync() can be started after
2454 /// any BufferCollectionToken.Duplicate() messages have been sent via the
2455 /// newly created token, to also sync those additional tokens to sysmem
2456 /// using a single round-trip.
2457 ///
2458 /// These values for rights_attenuation_mask result in no attenuation (note
2459 /// that 0 is not on this list; 0 will output an ERROR to the system log
2460 /// to help diagnose the bug in client code):
2461 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
2462 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
2463 pub fn r#attach_token(
2464 &self,
2465 mut rights_attenuation_mask: u32,
2466 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
2467 ) -> Result<(), fidl::Error> {
2468 BufferCollectionProxyInterface::r#attach_token(self, rights_attenuation_mask, token_request)
2469 }
2470
2471 /// AttachLifetimeTracking:
2472 ///
2473 /// AttachLifetimeTracking() is intended to allow a client to wait until an
2474 /// old logical buffer collection is fully or mostly deallocated before
2475 /// attempting allocation of a new logical buffer collection.
2476 ///
2477 /// Attach an eventpair endpoint to the logical buffer collection, so that
2478 /// the server_end will be closed when the number of buffers allocated
2479 /// drops to 'buffers_remaining'. The server_end won't close until after
2480 /// logical allocation has completed.
2481 ///
2482 /// If logical allocation fails, such as for an attached sub-tree (using
2483 /// AttachToken()), the server_end will close during that failure regardless
2484 /// of the number of buffers potenitally allocated in the overall logical
2485 /// buffer collection.
2486 ///
2487 /// The lifetime signalled by this event includes asynchronous cleanup of
2488 /// allocated buffers, and this asynchronous cleanup cannot occur until all
2489 /// holders of VMO handles to the buffers have closed those VMO handles.
2490 /// Therefore clients should take care not to become blocked forever waiting
2491 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
2492 /// participants using the logical buffer collection are less trusted or
2493 /// less reliable.
2494 ///
2495 /// The buffers_remaining parameter allows waiting for all but
2496 /// buffers_remaining buffers to be fully deallocated. This can be useful
2497 /// in situations where a known number of buffers are intentionally not
2498 /// closed so that the data can continue to be used, such as for keeping the
2499 /// last available video picture displayed in the UI even if the video
2500 /// stream was using protected output buffers. It's outside the scope of
2501 /// the BufferCollection interface (at least for now) to determine how many
2502 /// buffers may be held without closing, but it'll typically be in the range
2503 /// 0-2.
2504 ///
2505 /// This mechanism is meant to be compatible with other protocols providing
2506 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
2507 /// same event can be sent to more than one AttachLifetimeTracking(), and
2508 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
2509 /// over conditions are met (all holders of duplicates have closed their
2510 /// handle(s)).
2511 ///
2512 /// There is no way to cancel an attach. Closing the client end of the
2513 /// eventpair doesn't subtract from the number of pending attach(es).
2514 ///
2515 /// Closing the client's end doesn't result in any action by the server.
2516 /// If the server listens to events from the client end at all, it is for
2517 /// debug logging only.
2518 ///
2519 /// The server intentionally doesn't "trust" any bits signalled by the
2520 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
2521 /// which can't be triggered early, and is only triggered when all handles
2522 /// to server_end are closed. No meaning is associated with any of the
2523 /// other signal bits, and clients should functionally ignore any other
2524 /// signal bits on either end of the eventpair or its peer.
2525 ///
2526 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
2527 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
2528 /// transfer without causing CodecFactory channel failure).
2529 pub fn r#attach_lifetime_tracking(
2530 &self,
2531 mut server_end: fidl::EventPair,
2532 mut buffers_remaining: u32,
2533 ) -> Result<(), fidl::Error> {
2534 BufferCollectionProxyInterface::r#attach_lifetime_tracking(
2535 self,
2536 server_end,
2537 buffers_remaining,
2538 )
2539 }
2540}
2541
2542impl BufferCollectionProxyInterface for BufferCollectionProxy {
2543 type SyncResponseFut =
2544 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
2545 fn r#sync(&self) -> Self::SyncResponseFut {
2546 fn _decode(
2547 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2548 ) -> Result<(), fidl::Error> {
2549 let _response = fidl::client::decode_transaction_body::<
2550 fidl::encoding::EmptyPayload,
2551 fidl::encoding::DefaultFuchsiaResourceDialect,
2552 0x4577e238ae26291,
2553 >(_buf?)?;
2554 Ok(_response)
2555 }
2556 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
2557 (),
2558 0x4577e238ae26291,
2559 fidl::encoding::DynamicFlags::empty(),
2560 _decode,
2561 )
2562 }
2563
2564 fn r#close(&self) -> Result<(), fidl::Error> {
2565 self.client.send::<fidl::encoding::EmptyPayload>(
2566 (),
2567 0x5b1d7a4f5681fca7,
2568 fidl::encoding::DynamicFlags::empty(),
2569 )
2570 }
2571
2572 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
2573 self.client.send::<NodeSetNameRequest>(
2574 (priority, name),
2575 0x77a41bb6217e2443,
2576 fidl::encoding::DynamicFlags::empty(),
2577 )
2578 }
2579
2580 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
2581 self.client.send::<NodeSetDebugClientInfoRequest>(
2582 (name, id),
2583 0x7275759070eb5ee2,
2584 fidl::encoding::DynamicFlags::empty(),
2585 )
2586 }
2587
2588 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
2589 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
2590 (deadline,),
2591 0x46d38f4772638867,
2592 fidl::encoding::DynamicFlags::empty(),
2593 )
2594 }
2595
2596 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
2597 self.client.send::<fidl::encoding::EmptyPayload>(
2598 (),
2599 0x6bfbe2cf1701d288,
2600 fidl::encoding::DynamicFlags::empty(),
2601 )
2602 }
2603
2604 type GetNodeRefResponseFut =
2605 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
2606 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
2607 fn _decode(
2608 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2609 ) -> Result<fidl::Event, fidl::Error> {
2610 let _response = fidl::client::decode_transaction_body::<
2611 NodeGetNodeRefResponse,
2612 fidl::encoding::DefaultFuchsiaResourceDialect,
2613 0x467b7c75c35c3b84,
2614 >(_buf?)?;
2615 Ok(_response.node_ref)
2616 }
2617 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
2618 (),
2619 0x467b7c75c35c3b84,
2620 fidl::encoding::DynamicFlags::empty(),
2621 _decode,
2622 )
2623 }
2624
2625 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
2626 NodeIsAlternateForResult,
2627 fidl::encoding::DefaultFuchsiaResourceDialect,
2628 >;
2629 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
2630 fn _decode(
2631 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2632 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
2633 let _response = fidl::client::decode_transaction_body::<
2634 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
2635 fidl::encoding::DefaultFuchsiaResourceDialect,
2636 0x33a2a7aff2776c07,
2637 >(_buf?)?;
2638 Ok(_response.map(|x| x.is_alternate))
2639 }
2640 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
2641 (node_ref,),
2642 0x33a2a7aff2776c07,
2643 fidl::encoding::DynamicFlags::empty(),
2644 _decode,
2645 )
2646 }
2647
2648 fn r#set_constraints(
2649 &self,
2650 mut has_constraints: bool,
2651 mut constraints: &BufferCollectionConstraints,
2652 ) -> Result<(), fidl::Error> {
2653 self.client.send::<BufferCollectionSetConstraintsRequest>(
2654 (has_constraints, constraints),
2655 0x4d9c3406c213227b,
2656 fidl::encoding::DynamicFlags::empty(),
2657 )
2658 }
2659
2660 type WaitForBuffersAllocatedResponseFut = fidl::client::QueryResponseFut<
2661 (i32, BufferCollectionInfo2),
2662 fidl::encoding::DefaultFuchsiaResourceDialect,
2663 >;
2664 fn r#wait_for_buffers_allocated(&self) -> Self::WaitForBuffersAllocatedResponseFut {
2665 fn _decode(
2666 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2667 ) -> Result<(i32, BufferCollectionInfo2), fidl::Error> {
2668 let _response = fidl::client::decode_transaction_body::<
2669 BufferCollectionWaitForBuffersAllocatedResponse,
2670 fidl::encoding::DefaultFuchsiaResourceDialect,
2671 0x714667ea2a29a3a2,
2672 >(_buf?)?;
2673 Ok((_response.status, _response.buffer_collection_info))
2674 }
2675 self.client
2676 .send_query_and_decode::<fidl::encoding::EmptyPayload, (i32, BufferCollectionInfo2)>(
2677 (),
2678 0x714667ea2a29a3a2,
2679 fidl::encoding::DynamicFlags::empty(),
2680 _decode,
2681 )
2682 }
2683
2684 type CheckBuffersAllocatedResponseFut =
2685 fidl::client::QueryResponseFut<i32, fidl::encoding::DefaultFuchsiaResourceDialect>;
2686 fn r#check_buffers_allocated(&self) -> Self::CheckBuffersAllocatedResponseFut {
2687 fn _decode(
2688 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2689 ) -> Result<i32, fidl::Error> {
2690 let _response = fidl::client::decode_transaction_body::<
2691 BufferCollectionCheckBuffersAllocatedResponse,
2692 fidl::encoding::DefaultFuchsiaResourceDialect,
2693 0x245bb81f79189e9,
2694 >(_buf?)?;
2695 Ok(_response.status)
2696 }
2697 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, i32>(
2698 (),
2699 0x245bb81f79189e9,
2700 fidl::encoding::DynamicFlags::empty(),
2701 _decode,
2702 )
2703 }
2704
2705 fn r#attach_token(
2706 &self,
2707 mut rights_attenuation_mask: u32,
2708 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
2709 ) -> Result<(), fidl::Error> {
2710 self.client.send::<BufferCollectionAttachTokenRequest>(
2711 (rights_attenuation_mask, token_request),
2712 0x6f5adcca4ac7443e,
2713 fidl::encoding::DynamicFlags::empty(),
2714 )
2715 }
2716
2717 fn r#attach_lifetime_tracking(
2718 &self,
2719 mut server_end: fidl::EventPair,
2720 mut buffers_remaining: u32,
2721 ) -> Result<(), fidl::Error> {
2722 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
2723 (server_end, buffers_remaining),
2724 0x170d0f1d89d50989,
2725 fidl::encoding::DynamicFlags::empty(),
2726 )
2727 }
2728}
2729
2730pub struct BufferCollectionEventStream {
2731 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
2732}
2733
2734impl std::marker::Unpin for BufferCollectionEventStream {}
2735
2736impl futures::stream::FusedStream for BufferCollectionEventStream {
2737 fn is_terminated(&self) -> bool {
2738 self.event_receiver.is_terminated()
2739 }
2740}
2741
2742impl futures::Stream for BufferCollectionEventStream {
2743 type Item = Result<BufferCollectionEvent, fidl::Error>;
2744
2745 fn poll_next(
2746 mut self: std::pin::Pin<&mut Self>,
2747 cx: &mut std::task::Context<'_>,
2748 ) -> std::task::Poll<Option<Self::Item>> {
2749 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
2750 &mut self.event_receiver,
2751 cx
2752 )?) {
2753 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionEvent::decode(buf))),
2754 None => std::task::Poll::Ready(None),
2755 }
2756 }
2757}
2758
2759#[derive(Debug)]
2760pub enum BufferCollectionEvent {}
2761
2762impl BufferCollectionEvent {
2763 /// Decodes a message buffer as a [`BufferCollectionEvent`].
2764 fn decode(
2765 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
2766 ) -> Result<BufferCollectionEvent, fidl::Error> {
2767 let (bytes, _handles) = buf.split_mut();
2768 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
2769 debug_assert_eq!(tx_header.tx_id, 0);
2770 match tx_header.ordinal {
2771 _ => Err(fidl::Error::UnknownOrdinal {
2772 ordinal: tx_header.ordinal,
2773 protocol_name:
2774 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
2775 }),
2776 }
2777 }
2778}
2779
2780/// A Stream of incoming requests for fuchsia.sysmem/BufferCollection.
2781pub struct BufferCollectionRequestStream {
2782 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2783 is_terminated: bool,
2784}
2785
2786impl std::marker::Unpin for BufferCollectionRequestStream {}
2787
2788impl futures::stream::FusedStream for BufferCollectionRequestStream {
2789 fn is_terminated(&self) -> bool {
2790 self.is_terminated
2791 }
2792}
2793
2794impl fidl::endpoints::RequestStream for BufferCollectionRequestStream {
2795 type Protocol = BufferCollectionMarker;
2796 type ControlHandle = BufferCollectionControlHandle;
2797
2798 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
2799 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
2800 }
2801
2802 fn control_handle(&self) -> Self::ControlHandle {
2803 BufferCollectionControlHandle { inner: self.inner.clone() }
2804 }
2805
2806 fn into_inner(
2807 self,
2808 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
2809 {
2810 (self.inner, self.is_terminated)
2811 }
2812
2813 fn from_inner(
2814 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2815 is_terminated: bool,
2816 ) -> Self {
2817 Self { inner, is_terminated }
2818 }
2819}
2820
2821impl futures::Stream for BufferCollectionRequestStream {
2822 type Item = Result<BufferCollectionRequest, fidl::Error>;
2823
2824 fn poll_next(
2825 mut self: std::pin::Pin<&mut Self>,
2826 cx: &mut std::task::Context<'_>,
2827 ) -> std::task::Poll<Option<Self::Item>> {
2828 let this = &mut *self;
2829 if this.inner.check_shutdown(cx) {
2830 this.is_terminated = true;
2831 return std::task::Poll::Ready(None);
2832 }
2833 if this.is_terminated {
2834 panic!("polled BufferCollectionRequestStream after completion");
2835 }
2836 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
2837 |bytes, handles| {
2838 match this.inner.channel().read_etc(cx, bytes, handles) {
2839 std::task::Poll::Ready(Ok(())) => {}
2840 std::task::Poll::Pending => return std::task::Poll::Pending,
2841 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
2842 this.is_terminated = true;
2843 return std::task::Poll::Ready(None);
2844 }
2845 std::task::Poll::Ready(Err(e)) => {
2846 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
2847 e.into(),
2848 ))));
2849 }
2850 }
2851
2852 // A message has been received from the channel
2853 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
2854
2855 std::task::Poll::Ready(Some(match header.ordinal {
2856 0x4577e238ae26291 => {
2857 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2858 let mut req = fidl::new_empty!(
2859 fidl::encoding::EmptyPayload,
2860 fidl::encoding::DefaultFuchsiaResourceDialect
2861 );
2862 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2863 let control_handle =
2864 BufferCollectionControlHandle { inner: this.inner.clone() };
2865 Ok(BufferCollectionRequest::Sync {
2866 responder: BufferCollectionSyncResponder {
2867 control_handle: std::mem::ManuallyDrop::new(control_handle),
2868 tx_id: header.tx_id,
2869 },
2870 })
2871 }
2872 0x5b1d7a4f5681fca7 => {
2873 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2874 let mut req = fidl::new_empty!(
2875 fidl::encoding::EmptyPayload,
2876 fidl::encoding::DefaultFuchsiaResourceDialect
2877 );
2878 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2879 let control_handle =
2880 BufferCollectionControlHandle { inner: this.inner.clone() };
2881 Ok(BufferCollectionRequest::Close { control_handle })
2882 }
2883 0x77a41bb6217e2443 => {
2884 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2885 let mut req = fidl::new_empty!(
2886 NodeSetNameRequest,
2887 fidl::encoding::DefaultFuchsiaResourceDialect
2888 );
2889 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
2890 let control_handle =
2891 BufferCollectionControlHandle { inner: this.inner.clone() };
2892 Ok(BufferCollectionRequest::SetName {
2893 priority: req.priority,
2894 name: req.name,
2895
2896 control_handle,
2897 })
2898 }
2899 0x7275759070eb5ee2 => {
2900 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2901 let mut req = fidl::new_empty!(
2902 NodeSetDebugClientInfoRequest,
2903 fidl::encoding::DefaultFuchsiaResourceDialect
2904 );
2905 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
2906 let control_handle =
2907 BufferCollectionControlHandle { inner: this.inner.clone() };
2908 Ok(BufferCollectionRequest::SetDebugClientInfo {
2909 name: req.name,
2910 id: req.id,
2911
2912 control_handle,
2913 })
2914 }
2915 0x46d38f4772638867 => {
2916 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2917 let mut req = fidl::new_empty!(
2918 NodeSetDebugTimeoutLogDeadlineRequest,
2919 fidl::encoding::DefaultFuchsiaResourceDialect
2920 );
2921 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
2922 let control_handle =
2923 BufferCollectionControlHandle { inner: this.inner.clone() };
2924 Ok(BufferCollectionRequest::SetDebugTimeoutLogDeadline {
2925 deadline: req.deadline,
2926
2927 control_handle,
2928 })
2929 }
2930 0x6bfbe2cf1701d288 => {
2931 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2932 let mut req = fidl::new_empty!(
2933 fidl::encoding::EmptyPayload,
2934 fidl::encoding::DefaultFuchsiaResourceDialect
2935 );
2936 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2937 let control_handle =
2938 BufferCollectionControlHandle { inner: this.inner.clone() };
2939 Ok(BufferCollectionRequest::SetVerboseLogging { control_handle })
2940 }
2941 0x467b7c75c35c3b84 => {
2942 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2943 let mut req = fidl::new_empty!(
2944 fidl::encoding::EmptyPayload,
2945 fidl::encoding::DefaultFuchsiaResourceDialect
2946 );
2947 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2948 let control_handle =
2949 BufferCollectionControlHandle { inner: this.inner.clone() };
2950 Ok(BufferCollectionRequest::GetNodeRef {
2951 responder: BufferCollectionGetNodeRefResponder {
2952 control_handle: std::mem::ManuallyDrop::new(control_handle),
2953 tx_id: header.tx_id,
2954 },
2955 })
2956 }
2957 0x33a2a7aff2776c07 => {
2958 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2959 let mut req = fidl::new_empty!(
2960 NodeIsAlternateForRequest,
2961 fidl::encoding::DefaultFuchsiaResourceDialect
2962 );
2963 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
2964 let control_handle =
2965 BufferCollectionControlHandle { inner: this.inner.clone() };
2966 Ok(BufferCollectionRequest::IsAlternateFor {
2967 node_ref: req.node_ref,
2968
2969 responder: BufferCollectionIsAlternateForResponder {
2970 control_handle: std::mem::ManuallyDrop::new(control_handle),
2971 tx_id: header.tx_id,
2972 },
2973 })
2974 }
2975 0x4d9c3406c213227b => {
2976 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2977 let mut req = fidl::new_empty!(
2978 BufferCollectionSetConstraintsRequest,
2979 fidl::encoding::DefaultFuchsiaResourceDialect
2980 );
2981 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionSetConstraintsRequest>(&header, _body_bytes, handles, &mut req)?;
2982 let control_handle =
2983 BufferCollectionControlHandle { inner: this.inner.clone() };
2984 Ok(BufferCollectionRequest::SetConstraints {
2985 has_constraints: req.has_constraints,
2986 constraints: req.constraints,
2987
2988 control_handle,
2989 })
2990 }
2991 0x714667ea2a29a3a2 => {
2992 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2993 let mut req = fidl::new_empty!(
2994 fidl::encoding::EmptyPayload,
2995 fidl::encoding::DefaultFuchsiaResourceDialect
2996 );
2997 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2998 let control_handle =
2999 BufferCollectionControlHandle { inner: this.inner.clone() };
3000 Ok(BufferCollectionRequest::WaitForBuffersAllocated {
3001 responder: BufferCollectionWaitForBuffersAllocatedResponder {
3002 control_handle: std::mem::ManuallyDrop::new(control_handle),
3003 tx_id: header.tx_id,
3004 },
3005 })
3006 }
3007 0x245bb81f79189e9 => {
3008 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
3009 let mut req = fidl::new_empty!(
3010 fidl::encoding::EmptyPayload,
3011 fidl::encoding::DefaultFuchsiaResourceDialect
3012 );
3013 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
3014 let control_handle =
3015 BufferCollectionControlHandle { inner: this.inner.clone() };
3016 Ok(BufferCollectionRequest::CheckBuffersAllocated {
3017 responder: BufferCollectionCheckBuffersAllocatedResponder {
3018 control_handle: std::mem::ManuallyDrop::new(control_handle),
3019 tx_id: header.tx_id,
3020 },
3021 })
3022 }
3023 0x6f5adcca4ac7443e => {
3024 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
3025 let mut req = fidl::new_empty!(
3026 BufferCollectionAttachTokenRequest,
3027 fidl::encoding::DefaultFuchsiaResourceDialect
3028 );
3029 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachTokenRequest>(&header, _body_bytes, handles, &mut req)?;
3030 let control_handle =
3031 BufferCollectionControlHandle { inner: this.inner.clone() };
3032 Ok(BufferCollectionRequest::AttachToken {
3033 rights_attenuation_mask: req.rights_attenuation_mask,
3034 token_request: req.token_request,
3035
3036 control_handle,
3037 })
3038 }
3039 0x170d0f1d89d50989 => {
3040 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
3041 let mut req = fidl::new_empty!(
3042 BufferCollectionAttachLifetimeTrackingRequest,
3043 fidl::encoding::DefaultFuchsiaResourceDialect
3044 );
3045 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachLifetimeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
3046 let control_handle =
3047 BufferCollectionControlHandle { inner: this.inner.clone() };
3048 Ok(BufferCollectionRequest::AttachLifetimeTracking {
3049 server_end: req.server_end,
3050 buffers_remaining: req.buffers_remaining,
3051
3052 control_handle,
3053 })
3054 }
3055 _ => Err(fidl::Error::UnknownOrdinal {
3056 ordinal: header.ordinal,
3057 protocol_name:
3058 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
3059 }),
3060 }))
3061 },
3062 )
3063 }
3064}
3065
3066/// BufferCollection is a connection directly from a participant to sysmem re.
3067/// a logical BufferCollection; typically the logical BufferCollection is shared
3068/// with other participants. In other words, an instance of the BufferCollection
3069/// interface is a view of a "logical buffer collection".
3070///
3071/// This connection exists to facilitate async indication of when the logical
3072/// BufferCollection has been populated with buffers.
3073///
3074/// Also, the channel's closure by the server is an indication to the client
3075/// that the client should close all VMO handles that were obtained from the
3076/// BufferCollection ASAP.
3077///
3078/// Also, this interface may in future allow specifying constraints in other
3079/// ways, and may allow for back-and-forth negotiation of constraints to some
3080/// degree.
3081///
3082/// This interface may in future allow for more than 64 VMO handles per
3083/// BufferCollection, but currently the limit is 64.
3084///
3085/// This interface may in future allow for allocating/deallocating single
3086/// buffers.
3087///
3088/// Some initiators may wait a short duration until all old logical
3089/// BufferCollection VMO handles have closed (or until the short duration times
3090/// out) before allocating a new BufferCollection, to help control physical
3091/// memory fragmentation and avoid overlap of buffer allocation lifetimes for
3092/// the old and new collections. Collections can be large enough that it's worth
3093/// avoiding allocation overlap (in time).
3094#[derive(Debug)]
3095pub enum BufferCollectionRequest {
3096 /// Ensure that previous messages, including Duplicate() messages on a
3097 /// token, collection, or group, have been received server side.
3098 ///
3099 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
3100 /// valid sysmem token risks the Sync() hanging forever. See
3101 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
3102 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
3103 /// Another way is to pass the token to BindSharedCollection(), which also
3104 /// validates the token as part of exchanging it for a BufferCollection
3105 /// channel, and BufferCollection Sync() can then be used.
3106 ///
3107 /// After a Sync(), it's then safe to send the client end of token_request
3108 /// to another participant knowing the server will recognize the token when
3109 /// it's sent into BindSharedCollection() by the other participant.
3110 ///
3111 /// Other options include waiting for each token.Duplicate() to complete
3112 /// individually (using separate call to token.Sync() after each), or
3113 /// calling Sync() on BufferCollection after the token has been turned in
3114 /// via BindSharedCollection().
3115 ///
3116 /// Another way to mitigate is to avoid calling Sync() on the token, and
3117 /// instead later deal with potential failure of BufferCollection.Sync() if
3118 /// the original token was invalid. This option can be preferable from a
3119 /// performance point of view, but requires client code to delay sending
3120 /// tokens duplicated from this token until after client code has converted
3121 /// the duplicating token to a BufferCollection and received successful
3122 /// response from BufferCollection.Sync().
3123 ///
3124 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
3125 /// When BufferCollection.Sync() isn't feasible, the caller must already
3126 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
3127 /// hang forever. See ValidateBufferCollectionToken() to check token
3128 /// validity first if the token isn't already known to be (is/was) valid.
3129 Sync { responder: BufferCollectionSyncResponder },
3130 /// On a BufferCollectionToken channel:
3131 ///
3132 /// Normally a participant will convert a BufferCollectionToken into a
3133 /// BufferCollection view, but a participant is also free to Close() the
3134 /// token (and then close the channel immediately or shortly later in
3135 /// response to server closing its end), which avoids causing logical buffer
3136 /// collection failure. Â Normally an unexpected token channel close will
3137 /// cause logical buffer collection failure (the only exceptions being
3138 /// certain cases involving AttachToken() or SetDispensable()).
3139 ///
3140 /// On a BufferCollection channel:
3141 ///
3142 /// By default the server handles unexpected failure of a BufferCollection
3143 /// by failing the whole logical buffer collection. Partly this is to
3144 /// expedite closing VMO handles to reclaim memory when any participant
3145 /// fails. If a participant would like to cleanly close a BufferCollection
3146 /// view without causing logical buffer collection failure, the participant
3147 /// can send Close() before closing the client end of the BufferCollection
3148 /// channel. If this is the last BufferCollection view, the logical buffer
3149 /// collection will still go away. The Close() can occur before or after
3150 /// SetConstraints(). If before SetConstraints(), the buffer collection
3151 /// won't require constraints from this node in order to allocate. If
3152 /// after SetConstraints(), the constraints are retained and aggregated
3153 /// along with any subsequent logical allocation(s), despite the lack of
3154 /// channel connection.
3155 ///
3156 /// On a BufferCollectionTokenGroup channel:
3157 ///
3158 /// By default, unexpected failure of a BufferCollectionTokenGroup will
3159 /// trigger failure of the logical BufferCollectionTokenGroup and will
3160 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
3161 /// channel without failing the logical group or propagating failure, send
3162 /// Close() before closing the channel client endpoint.
3163 ///
3164 /// If Close() occurs before AllChildrenPresent(), the logical buffer
3165 /// collection will still fail despite the Close() (because sysmem can't be
3166 /// sure whether all relevant children were created, so it's ambiguous
3167 /// whether all relevant constraints will be provided to sysmem). If
3168 /// Close() occurs after AllChildrenPresent(), the children and all their
3169 /// constraints remain intact (just as they would if the
3170 /// BufferCollectionTokenGroup channel had remained open), and the close
3171 /// doesn't trigger or propagate failure.
3172 Close { control_handle: BufferCollectionControlHandle },
3173 /// Set a name for VMOs in this buffer collection. The name may be truncated
3174 /// shorter. The name only affects VMOs allocated after it's set - this call
3175 /// does not rename existing VMOs. If multiple clients set different names
3176 /// then the larger priority value will win.
3177 SetName { priority: u32, name: String, control_handle: BufferCollectionControlHandle },
3178 /// Set information about the current client that can be used by sysmem to
3179 /// help debug leaking memory and hangs waiting for constraints. |name| can
3180 /// be an arbitrary string, but the current process name (see
3181 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
3182 /// arbitrary id, but the current process ID (see
3183 /// fsl::GetCurrentProcessKoid()) is a good default.
3184 ///
3185 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
3186 /// indicate which client is closing their channel first, leading to
3187 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
3188 /// over, but if happening earlier than expected, the
3189 /// client-channel-specific name can help diagnose where the failure is
3190 /// first coming from, from sysmem's point of view).
3191 ///
3192 /// By default (unless overriden by this message or using
3193 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
3194 /// parent Node at the time the child Node is created. While this can be
3195 /// better than nothing, it's often better for each participant to use
3196 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
3197 /// info directly relevant to the current client. Also, SetVerboseLogging()
3198 /// can be used to help disambiguate if a Node is suspected of having info
3199 /// that was copied from its parent.
3200 SetDebugClientInfo { name: String, id: u64, control_handle: BufferCollectionControlHandle },
3201 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
3202 /// after creating a collection. Clients can call this method to change
3203 /// when the log is printed. If multiple client set the deadline, it's
3204 /// unspecified which deadline will take effect.
3205 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: BufferCollectionControlHandle },
3206 /// Verbose logging includes constraints set via SetConstraints() from each
3207 /// client along with info set via SetDebugClientInfo() and the structure of
3208 /// the tree of Node(s).
3209 ///
3210 /// Normally sysmem prints only a single line complaint when aggregation
3211 /// fails, with just the specific detailed reason that aggregation failed,
3212 /// with minimal context. While this is often enough to diagnose a problem
3213 /// if only a small change was made and the system had been working before
3214 /// the small change, it's often not particularly helpful for getting a new
3215 /// buffer collection to work for the first time. Especially with more
3216 /// complex trees of nodes, involving things like AttachToken(),
3217 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
3218 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
3219 /// looks like and why it's failing a logical allocation, or why a tree or
3220 /// sub-tree is failing sooner than expected.
3221 ///
3222 /// The intent of the extra logging is to be acceptable from a performance
3223 /// point of view, if only enabled on a low number of buffer collections.
3224 /// If we're not tracking down a bug, we shouldn't send this message.
3225 ///
3226 /// If too many participants leave verbose logging enabled, we may end up
3227 /// needing to require that system-wide sysmem verbose logging be permitted
3228 /// via some other setting, to avoid sysmem spamming the log too much due to
3229 /// this message.
3230 ///
3231 /// This may be a NOP for some nodes due to intentional policy associated
3232 /// with the node, if we don't trust a node enough to let it turn on verbose
3233 /// logging.
3234 SetVerboseLogging { control_handle: BufferCollectionControlHandle },
3235 /// This gets an event handle that can be used as a parameter to
3236 /// IsAlternateFor() called on any Node. The client will not be granted the
3237 /// right to signal this event, as this handle should only be used as proof
3238 /// that the client obtained this handle from this Node.
3239 ///
3240 /// Because this is a get not a set, no Sync() is needed between the
3241 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
3242 /// potentially being on different channels.
3243 ///
3244 /// See also IsAlternateFor().
3245 GetNodeRef { responder: BufferCollectionGetNodeRefResponder },
3246 /// This checks whether the calling node is in a subtree rooted at a
3247 /// different child token of a common parent BufferCollectionTokenGroup, in
3248 /// relation to the passed-in node_ref.
3249 ///
3250 /// This call is for assisting with admission control de-duplication, and
3251 /// with debugging.
3252 ///
3253 /// The node_ref must be obtained using GetNodeRef() of a
3254 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
3255 ///
3256 /// The node_ref can be a duplicated handle; it's not necessary to call
3257 /// GetNodeRef() for every call to IsAlternateFor().
3258 ///
3259 /// If a calling token may not actually be a valid token at all due to
3260 /// a potentially hostile/untrusted provider of the token, call
3261 /// ValidateBufferCollectionToken() first instead of potentially getting
3262 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
3263 /// token not being a real token (not really talking to sysmem). Another
3264 /// option is to call BindSharedCollection with this token first which also
3265 /// validates the token along with converting it to a BufferCollection, then
3266 /// call BufferCollection IsAlternateFor().
3267 ///
3268 /// error values:
3269 ///
3270 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
3271 /// buffer collection as the calling Node. Before logical allocation and
3272 /// within the same logical allocation sub-tree, this essentially means that
3273 /// the node_ref was never part of this logical buffer collection, since
3274 /// before logical allocation all node_refs that come into existence remain
3275 /// in existence at least until logical allocation (including Node(s) that
3276 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
3277 /// to be returned, this Node's channel needs to still be connected server
3278 /// side, which won't be the case if the whole logical allocation has
3279 /// failed. After logical allocation or in a different logical allocation
3280 /// sub-tree there are additional potential reasons for this error. For
3281 /// example a different logical allocation (separated from this Node(s)
3282 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
3283 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
3284 /// exist and may select a different child sub-tree than the sub-tree the
3285 /// node_ref is in causing deletion of the node_ref Node. The only time
3286 /// sysmem keeps a Node around after that Node has no corresponding channel
3287 /// is when Close() is used and the Node's sub-tree has not yet failed.
3288 /// Another reason for this error is if the node_ref is an eventpair handle
3289 /// with sufficient rights, but isn't actually a real node_ref obtained from
3290 /// GetNodeRef().
3291 ///
3292 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
3293 /// eventpair handle, or doesn't have the needed rights expected on a real
3294 /// node_ref.
3295 ///
3296 /// No other failing status codes are returned by this call. However,
3297 /// sysmem may add additional codes in future, so the client should have
3298 /// sensible default handling for any failing status code.
3299 ///
3300 /// On success, is_alternate has the following meaning:
3301 /// * true - The first parent node in common between the calling node and
3302 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
3303 /// the calling Node and the node_ref Node will _not_ have both their
3304 /// constraints apply - rather sysmem will choose one or the other of
3305 /// the constraints - never both. This is because only one child of
3306 /// a BufferCollectionTokenGroup is selected during logical allocation,
3307 /// with only that one child's sub-tree contributing to constraints
3308 /// aggregation.
3309 /// * false - The first parent node in common between the calling Node and
3310 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
3311 /// this means the first parent node in common is a
3312 /// BufferCollectionToken or BufferCollection (regardless of not
3313 /// Close()ed or Close()ed). This means that the calling Node and the
3314 /// node_ref Node _may_ have both their constraints apply during
3315 /// constraints aggregation of the logical allocation, if both Node(s)
3316 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
3317 /// In this case, there is no BufferCollectionTokenGroup that will
3318 /// directly prevent the two Node(s) from both being selected and their
3319 /// constraints both aggregated, but even when false, one or both
3320 /// Node(s) may still be eliminated from consideration if one or both
3321 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
3322 /// which selects a child sub-tree other than the sub-tree containing
3323 /// the calling Node or node_ref Node.
3324 IsAlternateFor { node_ref: fidl::Event, responder: BufferCollectionIsAlternateForResponder },
3325 /// Provide BufferCollectionConstraints to the logical BufferCollection.
3326 ///
3327 /// A participant may only call SetConstraints() once.
3328 ///
3329 /// Sometimes the initiator is a participant only in the sense of wanting to
3330 /// keep an eye on success/failure to populate with buffers, and zx.Status
3331 /// on failure. In that case, `has_constraints` can be false, and
3332 /// `constraints` will be ignored.
3333 ///
3334 /// VMO handles will not be provided to the client that sends null
3335 /// constraints - that can be intentional for an initiator that doesn't need
3336 /// VMO handles. Not having VMO handles doesn't prevent the initator from
3337 /// adjusting which portion of a buffer is considered valid and similar, but
3338 /// the initiator can't hold a VMO handle open to prevent the logical
3339 /// BufferCollection from cleaning up if the logical BufferCollection needs
3340 /// to go away regardless of the initiator's degree of involvement for
3341 /// whatever reason.
3342 ///
3343 /// For population of buffers to be attempted, all holders of a
3344 /// BufferCollection client channel need to call SetConstraints() before
3345 /// sysmem will attempt to allocate buffers.
3346 ///
3347 /// `has_constraints` if false, the constraints are effectively null, and
3348 /// `constraints` are ignored. The sender of null constraints won't get any
3349 /// VMO handles in BufferCollectionInfo, but can still find out how many
3350 /// buffers were allocated and can still refer to buffers by their
3351 /// buffer_index.
3352 ///
3353 /// `constraints` are constraints on the buffer collection.
3354 SetConstraints {
3355 has_constraints: bool,
3356 constraints: BufferCollectionConstraints,
3357 control_handle: BufferCollectionControlHandle,
3358 },
3359 /// This request completes when buffers have been allocated, responds with
3360 /// some failure detail if allocation has been attempted but failed.
3361 ///
3362 /// The following must occur before buffers will be allocated:
3363 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
3364 /// must be turned in via BindSharedCollection().
3365 /// * All BufferCollection(s) of the logical BufferCollection must have
3366 /// had SetConstraints() sent to them.
3367 ///
3368 /// Returns `ZX_OK` if successful.
3369 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
3370 /// fulfilled due to resource exhaustion.
3371 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
3372 /// obtain the buffers it requested.
3373 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
3374 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
3375 /// satisfied, perhaps due to hardware limitations.
3376 ///
3377 /// `buffer_collection_info` has the VMO handles and other related info.
3378 WaitForBuffersAllocated { responder: BufferCollectionWaitForBuffersAllocatedResponder },
3379 /// This returns the same result code as WaitForBuffersAllocated if the
3380 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
3381 /// if WaitForBuffersAllocated would block.
3382 CheckBuffersAllocated { responder: BufferCollectionCheckBuffersAllocatedResponder },
3383 /// Create a new token, for trying to add a new participant to an existing
3384 /// collection, if the existing collection's buffer counts, constraints,
3385 /// and participants allow.
3386 ///
3387 /// This can be useful in replacing a failed participant, and/or in
3388 /// adding/re-adding a participant after buffers have already been
3389 /// allocated.
3390 ///
3391 /// Failure of an attached token / collection does not propagate to the
3392 /// parent of the attached token. Failure does propagate from a normal
3393 /// child of a dispensable token to the dispensable token. Failure
3394 /// of a child is blocked from reaching its parent if the child is attached,
3395 /// or if the child is dispensable and the failure occurred after logical
3396 /// allocation.
3397 ///
3398 /// An initiator may in some scenarios choose to initially use a dispensable
3399 /// token for a given instance of a participant, and then later if the first
3400 /// instance of that participant fails, a new second instance of that
3401 /// participant my be given a token created with AttachToken().
3402 ///
3403 /// From the point of view of the client end of the BufferCollectionToken
3404 /// channel, the token acts like any other token. The client can
3405 /// Duplicate() the token as needed, and can send the token to a different
3406 /// process. The token should be converted to a BufferCollection channel
3407 /// as normal by calling BindSharedCollection(). SetConstraints() should
3408 /// be called on that BufferCollection channel.
3409 ///
3410 /// A success result from WaitForBuffersAllocated() means the new
3411 /// participant's constraints were satisfiable using the already-existing
3412 /// buffer collection, the already-established BufferCollectionInfo
3413 /// including image format constraints, and the already-existing other
3414 /// participants and their buffer counts. A failure result means the new
3415 /// participant's constraints cannot be satisfied using the existing
3416 /// buffer collection and its already-logically-allocated participants.
3417 /// Creating a new collection instead may allow all participant's
3418 /// constraints to be satisfied, assuming SetDispensable() is used in place
3419 /// of AttachToken(), or a normal token is used.
3420 ///
3421 /// A token created with AttachToken() performs constraints aggregation with
3422 /// all constraints currently in effect on the buffer collection, plus the
3423 /// attached token under consideration plus child tokens under the attached
3424 /// token which are not themselves an attached token or under such a token.
3425 ///
3426 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
3427 /// first-come first-served, but a child can't logically allocate before
3428 /// all its parents have sent SetConstraints().
3429 ///
3430 /// See also SetDispensable(), which in contrast to AttachToken(), has the
3431 /// created token + children participate in constraints aggregation along
3432 /// with its parent.
3433 ///
3434 /// The newly created token needs to be Sync()ed to sysmem before the new
3435 /// token can be passed to BindSharedCollection(). The Sync() of the new
3436 /// token can be accomplished with BufferCollection.Sync() on this
3437 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
3438 /// token also works. A BufferCollectionToken.Sync() can be started after
3439 /// any BufferCollectionToken.Duplicate() messages have been sent via the
3440 /// newly created token, to also sync those additional tokens to sysmem
3441 /// using a single round-trip.
3442 ///
3443 /// These values for rights_attenuation_mask result in no attenuation (note
3444 /// that 0 is not on this list; 0 will output an ERROR to the system log
3445 /// to help diagnose the bug in client code):
3446 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
3447 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
3448 AttachToken {
3449 rights_attenuation_mask: u32,
3450 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
3451 control_handle: BufferCollectionControlHandle,
3452 },
3453 /// AttachLifetimeTracking:
3454 ///
3455 /// AttachLifetimeTracking() is intended to allow a client to wait until an
3456 /// old logical buffer collection is fully or mostly deallocated before
3457 /// attempting allocation of a new logical buffer collection.
3458 ///
3459 /// Attach an eventpair endpoint to the logical buffer collection, so that
3460 /// the server_end will be closed when the number of buffers allocated
3461 /// drops to 'buffers_remaining'. The server_end won't close until after
3462 /// logical allocation has completed.
3463 ///
3464 /// If logical allocation fails, such as for an attached sub-tree (using
3465 /// AttachToken()), the server_end will close during that failure regardless
3466 /// of the number of buffers potenitally allocated in the overall logical
3467 /// buffer collection.
3468 ///
3469 /// The lifetime signalled by this event includes asynchronous cleanup of
3470 /// allocated buffers, and this asynchronous cleanup cannot occur until all
3471 /// holders of VMO handles to the buffers have closed those VMO handles.
3472 /// Therefore clients should take care not to become blocked forever waiting
3473 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
3474 /// participants using the logical buffer collection are less trusted or
3475 /// less reliable.
3476 ///
3477 /// The buffers_remaining parameter allows waiting for all but
3478 /// buffers_remaining buffers to be fully deallocated. This can be useful
3479 /// in situations where a known number of buffers are intentionally not
3480 /// closed so that the data can continue to be used, such as for keeping the
3481 /// last available video picture displayed in the UI even if the video
3482 /// stream was using protected output buffers. It's outside the scope of
3483 /// the BufferCollection interface (at least for now) to determine how many
3484 /// buffers may be held without closing, but it'll typically be in the range
3485 /// 0-2.
3486 ///
3487 /// This mechanism is meant to be compatible with other protocols providing
3488 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
3489 /// same event can be sent to more than one AttachLifetimeTracking(), and
3490 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
3491 /// over conditions are met (all holders of duplicates have closed their
3492 /// handle(s)).
3493 ///
3494 /// There is no way to cancel an attach. Closing the client end of the
3495 /// eventpair doesn't subtract from the number of pending attach(es).
3496 ///
3497 /// Closing the client's end doesn't result in any action by the server.
3498 /// If the server listens to events from the client end at all, it is for
3499 /// debug logging only.
3500 ///
3501 /// The server intentionally doesn't "trust" any bits signalled by the
3502 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
3503 /// which can't be triggered early, and is only triggered when all handles
3504 /// to server_end are closed. No meaning is associated with any of the
3505 /// other signal bits, and clients should functionally ignore any other
3506 /// signal bits on either end of the eventpair or its peer.
3507 ///
3508 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
3509 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
3510 /// transfer without causing CodecFactory channel failure).
3511 AttachLifetimeTracking {
3512 server_end: fidl::EventPair,
3513 buffers_remaining: u32,
3514 control_handle: BufferCollectionControlHandle,
3515 },
3516}
3517
3518impl BufferCollectionRequest {
3519 #[allow(irrefutable_let_patterns)]
3520 pub fn into_sync(self) -> Option<(BufferCollectionSyncResponder)> {
3521 if let BufferCollectionRequest::Sync { responder } = self {
3522 Some((responder))
3523 } else {
3524 None
3525 }
3526 }
3527
3528 #[allow(irrefutable_let_patterns)]
3529 pub fn into_close(self) -> Option<(BufferCollectionControlHandle)> {
3530 if let BufferCollectionRequest::Close { control_handle } = self {
3531 Some((control_handle))
3532 } else {
3533 None
3534 }
3535 }
3536
3537 #[allow(irrefutable_let_patterns)]
3538 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionControlHandle)> {
3539 if let BufferCollectionRequest::SetName { priority, name, control_handle } = self {
3540 Some((priority, name, control_handle))
3541 } else {
3542 None
3543 }
3544 }
3545
3546 #[allow(irrefutable_let_patterns)]
3547 pub fn into_set_debug_client_info(
3548 self,
3549 ) -> Option<(String, u64, BufferCollectionControlHandle)> {
3550 if let BufferCollectionRequest::SetDebugClientInfo { name, id, control_handle } = self {
3551 Some((name, id, control_handle))
3552 } else {
3553 None
3554 }
3555 }
3556
3557 #[allow(irrefutable_let_patterns)]
3558 pub fn into_set_debug_timeout_log_deadline(
3559 self,
3560 ) -> Option<(i64, BufferCollectionControlHandle)> {
3561 if let BufferCollectionRequest::SetDebugTimeoutLogDeadline { deadline, control_handle } =
3562 self
3563 {
3564 Some((deadline, control_handle))
3565 } else {
3566 None
3567 }
3568 }
3569
3570 #[allow(irrefutable_let_patterns)]
3571 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionControlHandle)> {
3572 if let BufferCollectionRequest::SetVerboseLogging { control_handle } = self {
3573 Some((control_handle))
3574 } else {
3575 None
3576 }
3577 }
3578
3579 #[allow(irrefutable_let_patterns)]
3580 pub fn into_get_node_ref(self) -> Option<(BufferCollectionGetNodeRefResponder)> {
3581 if let BufferCollectionRequest::GetNodeRef { responder } = self {
3582 Some((responder))
3583 } else {
3584 None
3585 }
3586 }
3587
3588 #[allow(irrefutable_let_patterns)]
3589 pub fn into_is_alternate_for(
3590 self,
3591 ) -> Option<(fidl::Event, BufferCollectionIsAlternateForResponder)> {
3592 if let BufferCollectionRequest::IsAlternateFor { node_ref, responder } = self {
3593 Some((node_ref, responder))
3594 } else {
3595 None
3596 }
3597 }
3598
3599 #[allow(irrefutable_let_patterns)]
3600 pub fn into_set_constraints(
3601 self,
3602 ) -> Option<(bool, BufferCollectionConstraints, BufferCollectionControlHandle)> {
3603 if let BufferCollectionRequest::SetConstraints {
3604 has_constraints,
3605 constraints,
3606 control_handle,
3607 } = self
3608 {
3609 Some((has_constraints, constraints, control_handle))
3610 } else {
3611 None
3612 }
3613 }
3614
3615 #[allow(irrefutable_let_patterns)]
3616 pub fn into_wait_for_buffers_allocated(
3617 self,
3618 ) -> Option<(BufferCollectionWaitForBuffersAllocatedResponder)> {
3619 if let BufferCollectionRequest::WaitForBuffersAllocated { responder } = self {
3620 Some((responder))
3621 } else {
3622 None
3623 }
3624 }
3625
3626 #[allow(irrefutable_let_patterns)]
3627 pub fn into_check_buffers_allocated(
3628 self,
3629 ) -> Option<(BufferCollectionCheckBuffersAllocatedResponder)> {
3630 if let BufferCollectionRequest::CheckBuffersAllocated { responder } = self {
3631 Some((responder))
3632 } else {
3633 None
3634 }
3635 }
3636
3637 #[allow(irrefutable_let_patterns)]
3638 pub fn into_attach_token(
3639 self,
3640 ) -> Option<(
3641 u32,
3642 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
3643 BufferCollectionControlHandle,
3644 )> {
3645 if let BufferCollectionRequest::AttachToken {
3646 rights_attenuation_mask,
3647 token_request,
3648 control_handle,
3649 } = self
3650 {
3651 Some((rights_attenuation_mask, token_request, control_handle))
3652 } else {
3653 None
3654 }
3655 }
3656
3657 #[allow(irrefutable_let_patterns)]
3658 pub fn into_attach_lifetime_tracking(
3659 self,
3660 ) -> Option<(fidl::EventPair, u32, BufferCollectionControlHandle)> {
3661 if let BufferCollectionRequest::AttachLifetimeTracking {
3662 server_end,
3663 buffers_remaining,
3664 control_handle,
3665 } = self
3666 {
3667 Some((server_end, buffers_remaining, control_handle))
3668 } else {
3669 None
3670 }
3671 }
3672
3673 /// Name of the method defined in FIDL
3674 pub fn method_name(&self) -> &'static str {
3675 match *self {
3676 BufferCollectionRequest::Sync { .. } => "sync",
3677 BufferCollectionRequest::Close { .. } => "close",
3678 BufferCollectionRequest::SetName { .. } => "set_name",
3679 BufferCollectionRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
3680 BufferCollectionRequest::SetDebugTimeoutLogDeadline { .. } => {
3681 "set_debug_timeout_log_deadline"
3682 }
3683 BufferCollectionRequest::SetVerboseLogging { .. } => "set_verbose_logging",
3684 BufferCollectionRequest::GetNodeRef { .. } => "get_node_ref",
3685 BufferCollectionRequest::IsAlternateFor { .. } => "is_alternate_for",
3686 BufferCollectionRequest::SetConstraints { .. } => "set_constraints",
3687 BufferCollectionRequest::WaitForBuffersAllocated { .. } => "wait_for_buffers_allocated",
3688 BufferCollectionRequest::CheckBuffersAllocated { .. } => "check_buffers_allocated",
3689 BufferCollectionRequest::AttachToken { .. } => "attach_token",
3690 BufferCollectionRequest::AttachLifetimeTracking { .. } => "attach_lifetime_tracking",
3691 }
3692 }
3693}
3694
3695#[derive(Debug, Clone)]
3696pub struct BufferCollectionControlHandle {
3697 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
3698}
3699
3700impl fidl::endpoints::ControlHandle for BufferCollectionControlHandle {
3701 fn shutdown(&self) {
3702 self.inner.shutdown()
3703 }
3704
3705 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
3706 self.inner.shutdown_with_epitaph(status)
3707 }
3708
3709 fn is_closed(&self) -> bool {
3710 self.inner.channel().is_closed()
3711 }
3712 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
3713 self.inner.channel().on_closed()
3714 }
3715
3716 #[cfg(target_os = "fuchsia")]
3717 fn signal_peer(
3718 &self,
3719 clear_mask: zx::Signals,
3720 set_mask: zx::Signals,
3721 ) -> Result<(), zx_status::Status> {
3722 use fidl::Peered;
3723 self.inner.channel().signal_peer(clear_mask, set_mask)
3724 }
3725}
3726
3727impl BufferCollectionControlHandle {}
3728
3729#[must_use = "FIDL methods require a response to be sent"]
3730#[derive(Debug)]
3731pub struct BufferCollectionSyncResponder {
3732 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3733 tx_id: u32,
3734}
3735
3736/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3737/// if the responder is dropped without sending a response, so that the client
3738/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3739impl std::ops::Drop for BufferCollectionSyncResponder {
3740 fn drop(&mut self) {
3741 self.control_handle.shutdown();
3742 // Safety: drops once, never accessed again
3743 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3744 }
3745}
3746
3747impl fidl::endpoints::Responder for BufferCollectionSyncResponder {
3748 type ControlHandle = BufferCollectionControlHandle;
3749
3750 fn control_handle(&self) -> &BufferCollectionControlHandle {
3751 &self.control_handle
3752 }
3753
3754 fn drop_without_shutdown(mut self) {
3755 // Safety: drops once, never accessed again due to mem::forget
3756 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3757 // Prevent Drop from running (which would shut down the channel)
3758 std::mem::forget(self);
3759 }
3760}
3761
3762impl BufferCollectionSyncResponder {
3763 /// Sends a response to the FIDL transaction.
3764 ///
3765 /// Sets the channel to shutdown if an error occurs.
3766 pub fn send(self) -> Result<(), fidl::Error> {
3767 let _result = self.send_raw();
3768 if _result.is_err() {
3769 self.control_handle.shutdown();
3770 }
3771 self.drop_without_shutdown();
3772 _result
3773 }
3774
3775 /// Similar to "send" but does not shutdown the channel if an error occurs.
3776 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
3777 let _result = self.send_raw();
3778 self.drop_without_shutdown();
3779 _result
3780 }
3781
3782 fn send_raw(&self) -> Result<(), fidl::Error> {
3783 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
3784 (),
3785 self.tx_id,
3786 0x4577e238ae26291,
3787 fidl::encoding::DynamicFlags::empty(),
3788 )
3789 }
3790}
3791
3792#[must_use = "FIDL methods require a response to be sent"]
3793#[derive(Debug)]
3794pub struct BufferCollectionGetNodeRefResponder {
3795 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3796 tx_id: u32,
3797}
3798
3799/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3800/// if the responder is dropped without sending a response, so that the client
3801/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3802impl std::ops::Drop for BufferCollectionGetNodeRefResponder {
3803 fn drop(&mut self) {
3804 self.control_handle.shutdown();
3805 // Safety: drops once, never accessed again
3806 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3807 }
3808}
3809
3810impl fidl::endpoints::Responder for BufferCollectionGetNodeRefResponder {
3811 type ControlHandle = BufferCollectionControlHandle;
3812
3813 fn control_handle(&self) -> &BufferCollectionControlHandle {
3814 &self.control_handle
3815 }
3816
3817 fn drop_without_shutdown(mut self) {
3818 // Safety: drops once, never accessed again due to mem::forget
3819 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3820 // Prevent Drop from running (which would shut down the channel)
3821 std::mem::forget(self);
3822 }
3823}
3824
3825impl BufferCollectionGetNodeRefResponder {
3826 /// Sends a response to the FIDL transaction.
3827 ///
3828 /// Sets the channel to shutdown if an error occurs.
3829 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3830 let _result = self.send_raw(node_ref);
3831 if _result.is_err() {
3832 self.control_handle.shutdown();
3833 }
3834 self.drop_without_shutdown();
3835 _result
3836 }
3837
3838 /// Similar to "send" but does not shutdown the channel if an error occurs.
3839 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3840 let _result = self.send_raw(node_ref);
3841 self.drop_without_shutdown();
3842 _result
3843 }
3844
3845 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3846 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
3847 (node_ref,),
3848 self.tx_id,
3849 0x467b7c75c35c3b84,
3850 fidl::encoding::DynamicFlags::empty(),
3851 )
3852 }
3853}
3854
3855#[must_use = "FIDL methods require a response to be sent"]
3856#[derive(Debug)]
3857pub struct BufferCollectionIsAlternateForResponder {
3858 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3859 tx_id: u32,
3860}
3861
3862/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3863/// if the responder is dropped without sending a response, so that the client
3864/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3865impl std::ops::Drop for BufferCollectionIsAlternateForResponder {
3866 fn drop(&mut self) {
3867 self.control_handle.shutdown();
3868 // Safety: drops once, never accessed again
3869 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3870 }
3871}
3872
3873impl fidl::endpoints::Responder for BufferCollectionIsAlternateForResponder {
3874 type ControlHandle = BufferCollectionControlHandle;
3875
3876 fn control_handle(&self) -> &BufferCollectionControlHandle {
3877 &self.control_handle
3878 }
3879
3880 fn drop_without_shutdown(mut self) {
3881 // Safety: drops once, never accessed again due to mem::forget
3882 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3883 // Prevent Drop from running (which would shut down the channel)
3884 std::mem::forget(self);
3885 }
3886}
3887
3888impl BufferCollectionIsAlternateForResponder {
3889 /// Sends a response to the FIDL transaction.
3890 ///
3891 /// Sets the channel to shutdown if an error occurs.
3892 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
3893 let _result = self.send_raw(result);
3894 if _result.is_err() {
3895 self.control_handle.shutdown();
3896 }
3897 self.drop_without_shutdown();
3898 _result
3899 }
3900
3901 /// Similar to "send" but does not shutdown the channel if an error occurs.
3902 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
3903 let _result = self.send_raw(result);
3904 self.drop_without_shutdown();
3905 _result
3906 }
3907
3908 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
3909 self.control_handle
3910 .inner
3911 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
3912 result.map(|is_alternate| (is_alternate,)),
3913 self.tx_id,
3914 0x33a2a7aff2776c07,
3915 fidl::encoding::DynamicFlags::empty(),
3916 )
3917 }
3918}
3919
3920#[must_use = "FIDL methods require a response to be sent"]
3921#[derive(Debug)]
3922pub struct BufferCollectionWaitForBuffersAllocatedResponder {
3923 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3924 tx_id: u32,
3925}
3926
3927/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3928/// if the responder is dropped without sending a response, so that the client
3929/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3930impl std::ops::Drop for BufferCollectionWaitForBuffersAllocatedResponder {
3931 fn drop(&mut self) {
3932 self.control_handle.shutdown();
3933 // Safety: drops once, never accessed again
3934 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3935 }
3936}
3937
3938impl fidl::endpoints::Responder for BufferCollectionWaitForBuffersAllocatedResponder {
3939 type ControlHandle = BufferCollectionControlHandle;
3940
3941 fn control_handle(&self) -> &BufferCollectionControlHandle {
3942 &self.control_handle
3943 }
3944
3945 fn drop_without_shutdown(mut self) {
3946 // Safety: drops once, never accessed again due to mem::forget
3947 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3948 // Prevent Drop from running (which would shut down the channel)
3949 std::mem::forget(self);
3950 }
3951}
3952
3953impl BufferCollectionWaitForBuffersAllocatedResponder {
3954 /// Sends a response to the FIDL transaction.
3955 ///
3956 /// Sets the channel to shutdown if an error occurs.
3957 pub fn send(
3958 self,
3959 mut status: i32,
3960 mut buffer_collection_info: BufferCollectionInfo2,
3961 ) -> Result<(), fidl::Error> {
3962 let _result = self.send_raw(status, buffer_collection_info);
3963 if _result.is_err() {
3964 self.control_handle.shutdown();
3965 }
3966 self.drop_without_shutdown();
3967 _result
3968 }
3969
3970 /// Similar to "send" but does not shutdown the channel if an error occurs.
3971 pub fn send_no_shutdown_on_err(
3972 self,
3973 mut status: i32,
3974 mut buffer_collection_info: BufferCollectionInfo2,
3975 ) -> Result<(), fidl::Error> {
3976 let _result = self.send_raw(status, buffer_collection_info);
3977 self.drop_without_shutdown();
3978 _result
3979 }
3980
3981 fn send_raw(
3982 &self,
3983 mut status: i32,
3984 mut buffer_collection_info: BufferCollectionInfo2,
3985 ) -> Result<(), fidl::Error> {
3986 self.control_handle.inner.send::<BufferCollectionWaitForBuffersAllocatedResponse>(
3987 (status, &mut buffer_collection_info),
3988 self.tx_id,
3989 0x714667ea2a29a3a2,
3990 fidl::encoding::DynamicFlags::empty(),
3991 )
3992 }
3993}
3994
3995#[must_use = "FIDL methods require a response to be sent"]
3996#[derive(Debug)]
3997pub struct BufferCollectionCheckBuffersAllocatedResponder {
3998 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3999 tx_id: u32,
4000}
4001
4002/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
4003/// if the responder is dropped without sending a response, so that the client
4004/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
4005impl std::ops::Drop for BufferCollectionCheckBuffersAllocatedResponder {
4006 fn drop(&mut self) {
4007 self.control_handle.shutdown();
4008 // Safety: drops once, never accessed again
4009 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4010 }
4011}
4012
4013impl fidl::endpoints::Responder for BufferCollectionCheckBuffersAllocatedResponder {
4014 type ControlHandle = BufferCollectionControlHandle;
4015
4016 fn control_handle(&self) -> &BufferCollectionControlHandle {
4017 &self.control_handle
4018 }
4019
4020 fn drop_without_shutdown(mut self) {
4021 // Safety: drops once, never accessed again due to mem::forget
4022 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4023 // Prevent Drop from running (which would shut down the channel)
4024 std::mem::forget(self);
4025 }
4026}
4027
4028impl BufferCollectionCheckBuffersAllocatedResponder {
4029 /// Sends a response to the FIDL transaction.
4030 ///
4031 /// Sets the channel to shutdown if an error occurs.
4032 pub fn send(self, mut status: i32) -> Result<(), fidl::Error> {
4033 let _result = self.send_raw(status);
4034 if _result.is_err() {
4035 self.control_handle.shutdown();
4036 }
4037 self.drop_without_shutdown();
4038 _result
4039 }
4040
4041 /// Similar to "send" but does not shutdown the channel if an error occurs.
4042 pub fn send_no_shutdown_on_err(self, mut status: i32) -> Result<(), fidl::Error> {
4043 let _result = self.send_raw(status);
4044 self.drop_without_shutdown();
4045 _result
4046 }
4047
4048 fn send_raw(&self, mut status: i32) -> Result<(), fidl::Error> {
4049 self.control_handle.inner.send::<BufferCollectionCheckBuffersAllocatedResponse>(
4050 (status,),
4051 self.tx_id,
4052 0x245bb81f79189e9,
4053 fidl::encoding::DynamicFlags::empty(),
4054 )
4055 }
4056}
4057
4058#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
4059pub struct BufferCollectionTokenMarker;
4060
4061impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenMarker {
4062 type Proxy = BufferCollectionTokenProxy;
4063 type RequestStream = BufferCollectionTokenRequestStream;
4064 #[cfg(target_os = "fuchsia")]
4065 type SynchronousProxy = BufferCollectionTokenSynchronousProxy;
4066
4067 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionToken";
4068}
4069
4070pub trait BufferCollectionTokenProxyInterface: Send + Sync {
4071 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
4072 fn r#sync(&self) -> Self::SyncResponseFut;
4073 fn r#close(&self) -> Result<(), fidl::Error>;
4074 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
4075 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
4076 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
4077 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
4078 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
4079 + Send;
4080 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
4081 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
4082 + Send;
4083 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
4084 type DuplicateSyncResponseFut: std::future::Future<
4085 Output = Result<
4086 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
4087 fidl::Error,
4088 >,
4089 > + Send;
4090 fn r#duplicate_sync(
4091 &self,
4092 rights_attenuation_masks: &[fidl::Rights],
4093 ) -> Self::DuplicateSyncResponseFut;
4094 fn r#duplicate(
4095 &self,
4096 rights_attenuation_mask: u32,
4097 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
4098 ) -> Result<(), fidl::Error>;
4099 fn r#set_dispensable(&self) -> Result<(), fidl::Error>;
4100 fn r#create_buffer_collection_token_group(
4101 &self,
4102 group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
4103 ) -> Result<(), fidl::Error>;
4104}
4105#[derive(Debug)]
4106#[cfg(target_os = "fuchsia")]
4107pub struct BufferCollectionTokenSynchronousProxy {
4108 client: fidl::client::sync::Client,
4109}
4110
4111#[cfg(target_os = "fuchsia")]
4112impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenSynchronousProxy {
4113 type Proxy = BufferCollectionTokenProxy;
4114 type Protocol = BufferCollectionTokenMarker;
4115
4116 fn from_channel(inner: fidl::Channel) -> Self {
4117 Self::new(inner)
4118 }
4119
4120 fn into_channel(self) -> fidl::Channel {
4121 self.client.into_channel()
4122 }
4123
4124 fn as_channel(&self) -> &fidl::Channel {
4125 self.client.as_channel()
4126 }
4127}
4128
4129#[cfg(target_os = "fuchsia")]
4130impl BufferCollectionTokenSynchronousProxy {
4131 pub fn new(channel: fidl::Channel) -> Self {
4132 let protocol_name =
4133 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
4134 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
4135 }
4136
4137 pub fn into_channel(self) -> fidl::Channel {
4138 self.client.into_channel()
4139 }
4140
4141 /// Waits until an event arrives and returns it. It is safe for other
4142 /// threads to make concurrent requests while waiting for an event.
4143 pub fn wait_for_event(
4144 &self,
4145 deadline: zx::MonotonicInstant,
4146 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
4147 BufferCollectionTokenEvent::decode(self.client.wait_for_event(deadline)?)
4148 }
4149
4150 /// Ensure that previous messages, including Duplicate() messages on a
4151 /// token, collection, or group, have been received server side.
4152 ///
4153 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
4154 /// valid sysmem token risks the Sync() hanging forever. See
4155 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
4156 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
4157 /// Another way is to pass the token to BindSharedCollection(), which also
4158 /// validates the token as part of exchanging it for a BufferCollection
4159 /// channel, and BufferCollection Sync() can then be used.
4160 ///
4161 /// After a Sync(), it's then safe to send the client end of token_request
4162 /// to another participant knowing the server will recognize the token when
4163 /// it's sent into BindSharedCollection() by the other participant.
4164 ///
4165 /// Other options include waiting for each token.Duplicate() to complete
4166 /// individually (using separate call to token.Sync() after each), or
4167 /// calling Sync() on BufferCollection after the token has been turned in
4168 /// via BindSharedCollection().
4169 ///
4170 /// Another way to mitigate is to avoid calling Sync() on the token, and
4171 /// instead later deal with potential failure of BufferCollection.Sync() if
4172 /// the original token was invalid. This option can be preferable from a
4173 /// performance point of view, but requires client code to delay sending
4174 /// tokens duplicated from this token until after client code has converted
4175 /// the duplicating token to a BufferCollection and received successful
4176 /// response from BufferCollection.Sync().
4177 ///
4178 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
4179 /// When BufferCollection.Sync() isn't feasible, the caller must already
4180 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
4181 /// hang forever. See ValidateBufferCollectionToken() to check token
4182 /// validity first if the token isn't already known to be (is/was) valid.
4183 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
4184 let _response =
4185 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
4186 (),
4187 0x4577e238ae26291,
4188 fidl::encoding::DynamicFlags::empty(),
4189 ___deadline,
4190 )?;
4191 Ok(_response)
4192 }
4193
4194 /// On a BufferCollectionToken channel:
4195 ///
4196 /// Normally a participant will convert a BufferCollectionToken into a
4197 /// BufferCollection view, but a participant is also free to Close() the
4198 /// token (and then close the channel immediately or shortly later in
4199 /// response to server closing its end), which avoids causing logical buffer
4200 /// collection failure. Â Normally an unexpected token channel close will
4201 /// cause logical buffer collection failure (the only exceptions being
4202 /// certain cases involving AttachToken() or SetDispensable()).
4203 ///
4204 /// On a BufferCollection channel:
4205 ///
4206 /// By default the server handles unexpected failure of a BufferCollection
4207 /// by failing the whole logical buffer collection. Partly this is to
4208 /// expedite closing VMO handles to reclaim memory when any participant
4209 /// fails. If a participant would like to cleanly close a BufferCollection
4210 /// view without causing logical buffer collection failure, the participant
4211 /// can send Close() before closing the client end of the BufferCollection
4212 /// channel. If this is the last BufferCollection view, the logical buffer
4213 /// collection will still go away. The Close() can occur before or after
4214 /// SetConstraints(). If before SetConstraints(), the buffer collection
4215 /// won't require constraints from this node in order to allocate. If
4216 /// after SetConstraints(), the constraints are retained and aggregated
4217 /// along with any subsequent logical allocation(s), despite the lack of
4218 /// channel connection.
4219 ///
4220 /// On a BufferCollectionTokenGroup channel:
4221 ///
4222 /// By default, unexpected failure of a BufferCollectionTokenGroup will
4223 /// trigger failure of the logical BufferCollectionTokenGroup and will
4224 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
4225 /// channel without failing the logical group or propagating failure, send
4226 /// Close() before closing the channel client endpoint.
4227 ///
4228 /// If Close() occurs before AllChildrenPresent(), the logical buffer
4229 /// collection will still fail despite the Close() (because sysmem can't be
4230 /// sure whether all relevant children were created, so it's ambiguous
4231 /// whether all relevant constraints will be provided to sysmem). If
4232 /// Close() occurs after AllChildrenPresent(), the children and all their
4233 /// constraints remain intact (just as they would if the
4234 /// BufferCollectionTokenGroup channel had remained open), and the close
4235 /// doesn't trigger or propagate failure.
4236 pub fn r#close(&self) -> Result<(), fidl::Error> {
4237 self.client.send::<fidl::encoding::EmptyPayload>(
4238 (),
4239 0x5b1d7a4f5681fca7,
4240 fidl::encoding::DynamicFlags::empty(),
4241 )
4242 }
4243
4244 /// Set a name for VMOs in this buffer collection. The name may be truncated
4245 /// shorter. The name only affects VMOs allocated after it's set - this call
4246 /// does not rename existing VMOs. If multiple clients set different names
4247 /// then the larger priority value will win.
4248 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
4249 self.client.send::<NodeSetNameRequest>(
4250 (priority, name),
4251 0x77a41bb6217e2443,
4252 fidl::encoding::DynamicFlags::empty(),
4253 )
4254 }
4255
4256 /// Set information about the current client that can be used by sysmem to
4257 /// help debug leaking memory and hangs waiting for constraints. |name| can
4258 /// be an arbitrary string, but the current process name (see
4259 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
4260 /// arbitrary id, but the current process ID (see
4261 /// fsl::GetCurrentProcessKoid()) is a good default.
4262 ///
4263 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
4264 /// indicate which client is closing their channel first, leading to
4265 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
4266 /// over, but if happening earlier than expected, the
4267 /// client-channel-specific name can help diagnose where the failure is
4268 /// first coming from, from sysmem's point of view).
4269 ///
4270 /// By default (unless overriden by this message or using
4271 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
4272 /// parent Node at the time the child Node is created. While this can be
4273 /// better than nothing, it's often better for each participant to use
4274 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
4275 /// info directly relevant to the current client. Also, SetVerboseLogging()
4276 /// can be used to help disambiguate if a Node is suspected of having info
4277 /// that was copied from its parent.
4278 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
4279 self.client.send::<NodeSetDebugClientInfoRequest>(
4280 (name, id),
4281 0x7275759070eb5ee2,
4282 fidl::encoding::DynamicFlags::empty(),
4283 )
4284 }
4285
4286 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
4287 /// after creating a collection. Clients can call this method to change
4288 /// when the log is printed. If multiple client set the deadline, it's
4289 /// unspecified which deadline will take effect.
4290 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
4291 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
4292 (deadline,),
4293 0x46d38f4772638867,
4294 fidl::encoding::DynamicFlags::empty(),
4295 )
4296 }
4297
4298 /// Verbose logging includes constraints set via SetConstraints() from each
4299 /// client along with info set via SetDebugClientInfo() and the structure of
4300 /// the tree of Node(s).
4301 ///
4302 /// Normally sysmem prints only a single line complaint when aggregation
4303 /// fails, with just the specific detailed reason that aggregation failed,
4304 /// with minimal context. While this is often enough to diagnose a problem
4305 /// if only a small change was made and the system had been working before
4306 /// the small change, it's often not particularly helpful for getting a new
4307 /// buffer collection to work for the first time. Especially with more
4308 /// complex trees of nodes, involving things like AttachToken(),
4309 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
4310 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
4311 /// looks like and why it's failing a logical allocation, or why a tree or
4312 /// sub-tree is failing sooner than expected.
4313 ///
4314 /// The intent of the extra logging is to be acceptable from a performance
4315 /// point of view, if only enabled on a low number of buffer collections.
4316 /// If we're not tracking down a bug, we shouldn't send this message.
4317 ///
4318 /// If too many participants leave verbose logging enabled, we may end up
4319 /// needing to require that system-wide sysmem verbose logging be permitted
4320 /// via some other setting, to avoid sysmem spamming the log too much due to
4321 /// this message.
4322 ///
4323 /// This may be a NOP for some nodes due to intentional policy associated
4324 /// with the node, if we don't trust a node enough to let it turn on verbose
4325 /// logging.
4326 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
4327 self.client.send::<fidl::encoding::EmptyPayload>(
4328 (),
4329 0x6bfbe2cf1701d288,
4330 fidl::encoding::DynamicFlags::empty(),
4331 )
4332 }
4333
4334 /// This gets an event handle that can be used as a parameter to
4335 /// IsAlternateFor() called on any Node. The client will not be granted the
4336 /// right to signal this event, as this handle should only be used as proof
4337 /// that the client obtained this handle from this Node.
4338 ///
4339 /// Because this is a get not a set, no Sync() is needed between the
4340 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
4341 /// potentially being on different channels.
4342 ///
4343 /// See also IsAlternateFor().
4344 pub fn r#get_node_ref(
4345 &self,
4346 ___deadline: zx::MonotonicInstant,
4347 ) -> Result<fidl::Event, fidl::Error> {
4348 let _response =
4349 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
4350 (),
4351 0x467b7c75c35c3b84,
4352 fidl::encoding::DynamicFlags::empty(),
4353 ___deadline,
4354 )?;
4355 Ok(_response.node_ref)
4356 }
4357
4358 /// This checks whether the calling node is in a subtree rooted at a
4359 /// different child token of a common parent BufferCollectionTokenGroup, in
4360 /// relation to the passed-in node_ref.
4361 ///
4362 /// This call is for assisting with admission control de-duplication, and
4363 /// with debugging.
4364 ///
4365 /// The node_ref must be obtained using GetNodeRef() of a
4366 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
4367 ///
4368 /// The node_ref can be a duplicated handle; it's not necessary to call
4369 /// GetNodeRef() for every call to IsAlternateFor().
4370 ///
4371 /// If a calling token may not actually be a valid token at all due to
4372 /// a potentially hostile/untrusted provider of the token, call
4373 /// ValidateBufferCollectionToken() first instead of potentially getting
4374 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
4375 /// token not being a real token (not really talking to sysmem). Another
4376 /// option is to call BindSharedCollection with this token first which also
4377 /// validates the token along with converting it to a BufferCollection, then
4378 /// call BufferCollection IsAlternateFor().
4379 ///
4380 /// error values:
4381 ///
4382 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
4383 /// buffer collection as the calling Node. Before logical allocation and
4384 /// within the same logical allocation sub-tree, this essentially means that
4385 /// the node_ref was never part of this logical buffer collection, since
4386 /// before logical allocation all node_refs that come into existence remain
4387 /// in existence at least until logical allocation (including Node(s) that
4388 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
4389 /// to be returned, this Node's channel needs to still be connected server
4390 /// side, which won't be the case if the whole logical allocation has
4391 /// failed. After logical allocation or in a different logical allocation
4392 /// sub-tree there are additional potential reasons for this error. For
4393 /// example a different logical allocation (separated from this Node(s)
4394 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
4395 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
4396 /// exist and may select a different child sub-tree than the sub-tree the
4397 /// node_ref is in causing deletion of the node_ref Node. The only time
4398 /// sysmem keeps a Node around after that Node has no corresponding channel
4399 /// is when Close() is used and the Node's sub-tree has not yet failed.
4400 /// Another reason for this error is if the node_ref is an eventpair handle
4401 /// with sufficient rights, but isn't actually a real node_ref obtained from
4402 /// GetNodeRef().
4403 ///
4404 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
4405 /// eventpair handle, or doesn't have the needed rights expected on a real
4406 /// node_ref.
4407 ///
4408 /// No other failing status codes are returned by this call. However,
4409 /// sysmem may add additional codes in future, so the client should have
4410 /// sensible default handling for any failing status code.
4411 ///
4412 /// On success, is_alternate has the following meaning:
4413 /// * true - The first parent node in common between the calling node and
4414 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
4415 /// the calling Node and the node_ref Node will _not_ have both their
4416 /// constraints apply - rather sysmem will choose one or the other of
4417 /// the constraints - never both. This is because only one child of
4418 /// a BufferCollectionTokenGroup is selected during logical allocation,
4419 /// with only that one child's sub-tree contributing to constraints
4420 /// aggregation.
4421 /// * false - The first parent node in common between the calling Node and
4422 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
4423 /// this means the first parent node in common is a
4424 /// BufferCollectionToken or BufferCollection (regardless of not
4425 /// Close()ed or Close()ed). This means that the calling Node and the
4426 /// node_ref Node _may_ have both their constraints apply during
4427 /// constraints aggregation of the logical allocation, if both Node(s)
4428 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
4429 /// In this case, there is no BufferCollectionTokenGroup that will
4430 /// directly prevent the two Node(s) from both being selected and their
4431 /// constraints both aggregated, but even when false, one or both
4432 /// Node(s) may still be eliminated from consideration if one or both
4433 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
4434 /// which selects a child sub-tree other than the sub-tree containing
4435 /// the calling Node or node_ref Node.
4436 pub fn r#is_alternate_for(
4437 &self,
4438 mut node_ref: fidl::Event,
4439 ___deadline: zx::MonotonicInstant,
4440 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
4441 let _response = self.client.send_query::<
4442 NodeIsAlternateForRequest,
4443 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
4444 >(
4445 (node_ref,),
4446 0x33a2a7aff2776c07,
4447 fidl::encoding::DynamicFlags::empty(),
4448 ___deadline,
4449 )?;
4450 Ok(_response.map(|x| x.is_alternate))
4451 }
4452
4453 /// This method can be used to add more participants prior to creating a
4454 /// shared BufferCollection. A new token will be returned for each entry in
4455 /// the `rights_attenuation_masks` array. The return value is the client
4456 /// ends of each new participant token.
4457 ///
4458 /// If the calling token may not actually be a valid token at all due to
4459 /// a potentially hostile/untrusted provider of the token, consider using
4460 /// ValidateBufferCollectionToken() first instead of potentially getting
4461 /// stuck indefinitely if DuplicateSync() never responds due to the calling
4462 /// token not being a real token.
4463 ///
4464 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
4465 /// after calling this method.
4466 ///
4467 /// All tokens must be turned in via BindSharedCollection() or Close() for a
4468 /// BufferCollection to be successfully created.
4469 ///
4470 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
4471 /// will be absent in the buffer VMO rights obtainable via the corresponding
4472 /// returned token. This allows an initiator or intermediary participant to
4473 /// attenuate the rights available to a participant. This does not allow a
4474 /// participant to gain rights that the participant doesn't already have.
4475 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
4476 /// attenuation should be applied.
4477 pub fn r#duplicate_sync(
4478 &self,
4479 mut rights_attenuation_masks: &[fidl::Rights],
4480 ___deadline: zx::MonotonicInstant,
4481 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error> {
4482 let _response = self.client.send_query::<
4483 BufferCollectionTokenDuplicateSyncRequest,
4484 BufferCollectionTokenDuplicateSyncResponse,
4485 >(
4486 (rights_attenuation_masks,),
4487 0x49ed7ab7cc19f18,
4488 fidl::encoding::DynamicFlags::empty(),
4489 ___deadline,
4490 )?;
4491 Ok(_response.tokens)
4492 }
4493
4494 /// This method can be used to add a participant prior to creating a shared
4495 /// BufferCollection. It should only be used instead of DuplicateSync in
4496 /// performance sensitive cases where it would be undesireable to wait for
4497 /// sysmem to respond as part of each duplicate.
4498 ///
4499 /// After sending one or more Duplicate() messages, and before sending the
4500 /// created tokens to other participants (or to other Allocator channels),
4501 /// the client should send a Sync() and wait for its response. The Sync()
4502 /// call can be made on the token, or on the BufferCollection obtained by
4503 /// passing this token to BindSharedCollection(). Either will ensure that
4504 /// the server knows about the tokens created via Duplicate() before the
4505 /// other participant sends the token to the server via separate Allocator
4506 /// channel.
4507 ///
4508 /// All tokens must be turned in via BindSharedCollection() or Close() for a
4509 /// BufferCollection to be successfully created.
4510 ///
4511 /// When a client calls BindSharedCollection() to turn in a
4512 /// BufferCollectionToken, the server will process all Duplicate() messages
4513 /// before closing down the BufferCollectionToken. This allows the client
4514 /// to Duplicate() and immediately turn in the BufferCollectionToken using
4515 /// BindSharedCollection, then later transfer the client end of token_request
4516 /// to another participant - the server will notice the existence of the
4517 /// token_request before considering this BufferCollectionToken fully closed.
4518 ///
4519 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
4520 /// absent in the buffer VMO rights obtainable via the client end of
4521 /// token_request. This allows an initiator or intermediary participant to
4522 /// attenuate the rights available to a participant. This does not allow a
4523 /// participant to gain rights that the participant doesn't already have.
4524 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
4525 /// attenuation should be applied.
4526 ///
4527 /// These values for rights_attenuation_mask result in no attenuation:
4528 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
4529 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
4530 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
4531 ///
4532 /// `token_request` is the server end of a BufferCollectionToken channel.
4533 /// The client end of this channel acts as another participant in creating the
4534 /// shared BufferCollection.
4535 pub fn r#duplicate(
4536 &self,
4537 mut rights_attenuation_mask: u32,
4538 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
4539 ) -> Result<(), fidl::Error> {
4540 self.client.send::<BufferCollectionTokenDuplicateRequest>(
4541 (rights_attenuation_mask, token_request),
4542 0x2f9f81bdde4b7292,
4543 fidl::encoding::DynamicFlags::empty(),
4544 )
4545 }
4546
4547 /// A dispensable token can fail after buffers are logically allocated
4548 /// without causing failure of its parent (if any).
4549 ///
4550 /// The dispensable token participates in constraints aggregation along with
4551 /// its parent before logical buffer allocation. If the dispensable token
4552 /// fails before buffers are logically allocated, the failure propagates to
4553 /// the dispensable token's parent.
4554 ///
4555 /// After buffers are logically allocated, failure of the dispensable token
4556 /// (or any child of the dispensable token) does not propagate to the
4557 /// dispensable token's parent. Failure does propagate from a normal
4558 /// child of a dispensable token to the dispensable token. Failure
4559 /// of a child is blocked from reaching its parent if the child is attached,
4560 /// or if the child is dispensable and the failure occurred after logical
4561 /// allocation.
4562 ///
4563 /// A dispensable token can be used in cases where a participant needs to
4564 /// provide constraints, but after buffers are allocated, the participant
4565 /// can fail without causing buffer collection failure from the parent's
4566 /// point of view.
4567 ///
4568 /// In contrast, AttachToken() can be used to create a token which does not
4569 /// participate in constraints aggregation with its parent, and whose
4570 /// failure at any time does not propagate to its parent, and whose delay
4571 /// providing constraints does not prevent the parent from completing its
4572 /// buffer allocation.
4573 ///
4574 /// An initiator may in some scenarios choose to initially use a dispensable
4575 /// token for a given instance of a participant, and then later if the first
4576 /// instance of that participant fails, a new second instance of that
4577 /// participant my be given a token created with AttachToken().
4578 ///
4579 /// If a client uses this message, the client should not rely on the
4580 /// client's own BufferCollectionToken or BufferCollection channel to close
4581 /// from the server end due to abrupt failure of any BufferCollectionToken
4582 /// or BufferCollection that the client has SetDispensable() and given out
4583 /// to another process. For this reason, the client should take extra care
4584 /// to notice failure of that other process via other means.
4585 ///
4586 /// While it is possible (and potentially useful) to SetDispensable() on a
4587 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
4588 /// replace a failed dispensable token that was a direct child of a group
4589 /// with a new token using AttachToken() (since there's no AttachToken() on
4590 /// a group). Instead, to enable AttachToken() replacement in this case,
4591 /// create an additional non-dispensable token (node) that's a direct child
4592 /// of the group and make the existing dispensable token a child of the
4593 /// additional token (node). This way, the additional token (node) that is
4594 /// a direct child of the group has BufferCollection.AttachToken() which can
4595 /// be used to replace the failed dispensable token.
4596 ///
4597 /// SetDispensable() on an already-dispensable token is idempotent.
4598 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
4599 self.client.send::<fidl::encoding::EmptyPayload>(
4600 (),
4601 0x76e4ec34fc2cf5b3,
4602 fidl::encoding::DynamicFlags::empty(),
4603 )
4604 }
4605
4606 /// Most sysmem clients and many participants don't need to care about this
4607 /// message or about BufferCollectionTokenGroup(s) in general.
4608 ///
4609 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
4610 /// tokens. The child tokens which are not selected during aggregation will
4611 /// fail (close), which a potential participant should notice when their
4612 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
4613 /// participant to clean up the speculative usage that didn't end up
4614 /// happening (similarly to a normal BufferCollection server end closing
4615 /// on failure of a logical buffer collection).
4616 ///
4617 /// See comments on protocol BufferCollectionTokenGroup.
4618 ///
4619 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
4620 /// applied to the whole group can be achieved with a token for this purpose
4621 /// as a direct parent of the group.
4622 ///
4623 /// group_request - the server end of a BufferCollectionTokenGroup channel
4624 /// to be served by sysmem.
4625 pub fn r#create_buffer_collection_token_group(
4626 &self,
4627 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
4628 ) -> Result<(), fidl::Error> {
4629 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
4630 (group_request,),
4631 0x2f6243e05f22b9a7,
4632 fidl::encoding::DynamicFlags::empty(),
4633 )
4634 }
4635}
4636
4637#[cfg(target_os = "fuchsia")]
4638impl From<BufferCollectionTokenSynchronousProxy> for zx::NullableHandle {
4639 fn from(value: BufferCollectionTokenSynchronousProxy) -> Self {
4640 value.into_channel().into()
4641 }
4642}
4643
4644#[cfg(target_os = "fuchsia")]
4645impl From<fidl::Channel> for BufferCollectionTokenSynchronousProxy {
4646 fn from(value: fidl::Channel) -> Self {
4647 Self::new(value)
4648 }
4649}
4650
4651#[cfg(target_os = "fuchsia")]
4652impl fidl::endpoints::FromClient for BufferCollectionTokenSynchronousProxy {
4653 type Protocol = BufferCollectionTokenMarker;
4654
4655 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>) -> Self {
4656 Self::new(value.into_channel())
4657 }
4658}
4659
4660#[derive(Debug, Clone)]
4661pub struct BufferCollectionTokenProxy {
4662 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
4663}
4664
4665impl fidl::endpoints::Proxy for BufferCollectionTokenProxy {
4666 type Protocol = BufferCollectionTokenMarker;
4667
4668 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
4669 Self::new(inner)
4670 }
4671
4672 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
4673 self.client.into_channel().map_err(|client| Self { client })
4674 }
4675
4676 fn as_channel(&self) -> &::fidl::AsyncChannel {
4677 self.client.as_channel()
4678 }
4679}
4680
4681impl BufferCollectionTokenProxy {
4682 /// Create a new Proxy for fuchsia.sysmem/BufferCollectionToken.
4683 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
4684 let protocol_name =
4685 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
4686 Self { client: fidl::client::Client::new(channel, protocol_name) }
4687 }
4688
4689 /// Get a Stream of events from the remote end of the protocol.
4690 ///
4691 /// # Panics
4692 ///
4693 /// Panics if the event stream was already taken.
4694 pub fn take_event_stream(&self) -> BufferCollectionTokenEventStream {
4695 BufferCollectionTokenEventStream { event_receiver: self.client.take_event_receiver() }
4696 }
4697
4698 /// Ensure that previous messages, including Duplicate() messages on a
4699 /// token, collection, or group, have been received server side.
4700 ///
4701 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
4702 /// valid sysmem token risks the Sync() hanging forever. See
4703 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
4704 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
4705 /// Another way is to pass the token to BindSharedCollection(), which also
4706 /// validates the token as part of exchanging it for a BufferCollection
4707 /// channel, and BufferCollection Sync() can then be used.
4708 ///
4709 /// After a Sync(), it's then safe to send the client end of token_request
4710 /// to another participant knowing the server will recognize the token when
4711 /// it's sent into BindSharedCollection() by the other participant.
4712 ///
4713 /// Other options include waiting for each token.Duplicate() to complete
4714 /// individually (using separate call to token.Sync() after each), or
4715 /// calling Sync() on BufferCollection after the token has been turned in
4716 /// via BindSharedCollection().
4717 ///
4718 /// Another way to mitigate is to avoid calling Sync() on the token, and
4719 /// instead later deal with potential failure of BufferCollection.Sync() if
4720 /// the original token was invalid. This option can be preferable from a
4721 /// performance point of view, but requires client code to delay sending
4722 /// tokens duplicated from this token until after client code has converted
4723 /// the duplicating token to a BufferCollection and received successful
4724 /// response from BufferCollection.Sync().
4725 ///
4726 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
4727 /// When BufferCollection.Sync() isn't feasible, the caller must already
4728 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
4729 /// hang forever. See ValidateBufferCollectionToken() to check token
4730 /// validity first if the token isn't already known to be (is/was) valid.
4731 pub fn r#sync(
4732 &self,
4733 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
4734 BufferCollectionTokenProxyInterface::r#sync(self)
4735 }
4736
4737 /// On a BufferCollectionToken channel:
4738 ///
4739 /// Normally a participant will convert a BufferCollectionToken into a
4740 /// BufferCollection view, but a participant is also free to Close() the
4741 /// token (and then close the channel immediately or shortly later in
4742 /// response to server closing its end), which avoids causing logical buffer
4743 /// collection failure. Â Normally an unexpected token channel close will
4744 /// cause logical buffer collection failure (the only exceptions being
4745 /// certain cases involving AttachToken() or SetDispensable()).
4746 ///
4747 /// On a BufferCollection channel:
4748 ///
4749 /// By default the server handles unexpected failure of a BufferCollection
4750 /// by failing the whole logical buffer collection. Partly this is to
4751 /// expedite closing VMO handles to reclaim memory when any participant
4752 /// fails. If a participant would like to cleanly close a BufferCollection
4753 /// view without causing logical buffer collection failure, the participant
4754 /// can send Close() before closing the client end of the BufferCollection
4755 /// channel. If this is the last BufferCollection view, the logical buffer
4756 /// collection will still go away. The Close() can occur before or after
4757 /// SetConstraints(). If before SetConstraints(), the buffer collection
4758 /// won't require constraints from this node in order to allocate. If
4759 /// after SetConstraints(), the constraints are retained and aggregated
4760 /// along with any subsequent logical allocation(s), despite the lack of
4761 /// channel connection.
4762 ///
4763 /// On a BufferCollectionTokenGroup channel:
4764 ///
4765 /// By default, unexpected failure of a BufferCollectionTokenGroup will
4766 /// trigger failure of the logical BufferCollectionTokenGroup and will
4767 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
4768 /// channel without failing the logical group or propagating failure, send
4769 /// Close() before closing the channel client endpoint.
4770 ///
4771 /// If Close() occurs before AllChildrenPresent(), the logical buffer
4772 /// collection will still fail despite the Close() (because sysmem can't be
4773 /// sure whether all relevant children were created, so it's ambiguous
4774 /// whether all relevant constraints will be provided to sysmem). If
4775 /// Close() occurs after AllChildrenPresent(), the children and all their
4776 /// constraints remain intact (just as they would if the
4777 /// BufferCollectionTokenGroup channel had remained open), and the close
4778 /// doesn't trigger or propagate failure.
4779 pub fn r#close(&self) -> Result<(), fidl::Error> {
4780 BufferCollectionTokenProxyInterface::r#close(self)
4781 }
4782
4783 /// Set a name for VMOs in this buffer collection. The name may be truncated
4784 /// shorter. The name only affects VMOs allocated after it's set - this call
4785 /// does not rename existing VMOs. If multiple clients set different names
4786 /// then the larger priority value will win.
4787 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
4788 BufferCollectionTokenProxyInterface::r#set_name(self, priority, name)
4789 }
4790
4791 /// Set information about the current client that can be used by sysmem to
4792 /// help debug leaking memory and hangs waiting for constraints. |name| can
4793 /// be an arbitrary string, but the current process name (see
4794 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
4795 /// arbitrary id, but the current process ID (see
4796 /// fsl::GetCurrentProcessKoid()) is a good default.
4797 ///
4798 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
4799 /// indicate which client is closing their channel first, leading to
4800 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
4801 /// over, but if happening earlier than expected, the
4802 /// client-channel-specific name can help diagnose where the failure is
4803 /// first coming from, from sysmem's point of view).
4804 ///
4805 /// By default (unless overriden by this message or using
4806 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
4807 /// parent Node at the time the child Node is created. While this can be
4808 /// better than nothing, it's often better for each participant to use
4809 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
4810 /// info directly relevant to the current client. Also, SetVerboseLogging()
4811 /// can be used to help disambiguate if a Node is suspected of having info
4812 /// that was copied from its parent.
4813 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
4814 BufferCollectionTokenProxyInterface::r#set_debug_client_info(self, name, id)
4815 }
4816
4817 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
4818 /// after creating a collection. Clients can call this method to change
4819 /// when the log is printed. If multiple client set the deadline, it's
4820 /// unspecified which deadline will take effect.
4821 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
4822 BufferCollectionTokenProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
4823 }
4824
4825 /// Verbose logging includes constraints set via SetConstraints() from each
4826 /// client along with info set via SetDebugClientInfo() and the structure of
4827 /// the tree of Node(s).
4828 ///
4829 /// Normally sysmem prints only a single line complaint when aggregation
4830 /// fails, with just the specific detailed reason that aggregation failed,
4831 /// with minimal context. While this is often enough to diagnose a problem
4832 /// if only a small change was made and the system had been working before
4833 /// the small change, it's often not particularly helpful for getting a new
4834 /// buffer collection to work for the first time. Especially with more
4835 /// complex trees of nodes, involving things like AttachToken(),
4836 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
4837 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
4838 /// looks like and why it's failing a logical allocation, or why a tree or
4839 /// sub-tree is failing sooner than expected.
4840 ///
4841 /// The intent of the extra logging is to be acceptable from a performance
4842 /// point of view, if only enabled on a low number of buffer collections.
4843 /// If we're not tracking down a bug, we shouldn't send this message.
4844 ///
4845 /// If too many participants leave verbose logging enabled, we may end up
4846 /// needing to require that system-wide sysmem verbose logging be permitted
4847 /// via some other setting, to avoid sysmem spamming the log too much due to
4848 /// this message.
4849 ///
4850 /// This may be a NOP for some nodes due to intentional policy associated
4851 /// with the node, if we don't trust a node enough to let it turn on verbose
4852 /// logging.
4853 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
4854 BufferCollectionTokenProxyInterface::r#set_verbose_logging(self)
4855 }
4856
4857 /// This gets an event handle that can be used as a parameter to
4858 /// IsAlternateFor() called on any Node. The client will not be granted the
4859 /// right to signal this event, as this handle should only be used as proof
4860 /// that the client obtained this handle from this Node.
4861 ///
4862 /// Because this is a get not a set, no Sync() is needed between the
4863 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
4864 /// potentially being on different channels.
4865 ///
4866 /// See also IsAlternateFor().
4867 pub fn r#get_node_ref(
4868 &self,
4869 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
4870 {
4871 BufferCollectionTokenProxyInterface::r#get_node_ref(self)
4872 }
4873
4874 /// This checks whether the calling node is in a subtree rooted at a
4875 /// different child token of a common parent BufferCollectionTokenGroup, in
4876 /// relation to the passed-in node_ref.
4877 ///
4878 /// This call is for assisting with admission control de-duplication, and
4879 /// with debugging.
4880 ///
4881 /// The node_ref must be obtained using GetNodeRef() of a
4882 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
4883 ///
4884 /// The node_ref can be a duplicated handle; it's not necessary to call
4885 /// GetNodeRef() for every call to IsAlternateFor().
4886 ///
4887 /// If a calling token may not actually be a valid token at all due to
4888 /// a potentially hostile/untrusted provider of the token, call
4889 /// ValidateBufferCollectionToken() first instead of potentially getting
4890 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
4891 /// token not being a real token (not really talking to sysmem). Another
4892 /// option is to call BindSharedCollection with this token first which also
4893 /// validates the token along with converting it to a BufferCollection, then
4894 /// call BufferCollection IsAlternateFor().
4895 ///
4896 /// error values:
4897 ///
4898 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
4899 /// buffer collection as the calling Node. Before logical allocation and
4900 /// within the same logical allocation sub-tree, this essentially means that
4901 /// the node_ref was never part of this logical buffer collection, since
4902 /// before logical allocation all node_refs that come into existence remain
4903 /// in existence at least until logical allocation (including Node(s) that
4904 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
4905 /// to be returned, this Node's channel needs to still be connected server
4906 /// side, which won't be the case if the whole logical allocation has
4907 /// failed. After logical allocation or in a different logical allocation
4908 /// sub-tree there are additional potential reasons for this error. For
4909 /// example a different logical allocation (separated from this Node(s)
4910 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
4911 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
4912 /// exist and may select a different child sub-tree than the sub-tree the
4913 /// node_ref is in causing deletion of the node_ref Node. The only time
4914 /// sysmem keeps a Node around after that Node has no corresponding channel
4915 /// is when Close() is used and the Node's sub-tree has not yet failed.
4916 /// Another reason for this error is if the node_ref is an eventpair handle
4917 /// with sufficient rights, but isn't actually a real node_ref obtained from
4918 /// GetNodeRef().
4919 ///
4920 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
4921 /// eventpair handle, or doesn't have the needed rights expected on a real
4922 /// node_ref.
4923 ///
4924 /// No other failing status codes are returned by this call. However,
4925 /// sysmem may add additional codes in future, so the client should have
4926 /// sensible default handling for any failing status code.
4927 ///
4928 /// On success, is_alternate has the following meaning:
4929 /// * true - The first parent node in common between the calling node and
4930 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
4931 /// the calling Node and the node_ref Node will _not_ have both their
4932 /// constraints apply - rather sysmem will choose one or the other of
4933 /// the constraints - never both. This is because only one child of
4934 /// a BufferCollectionTokenGroup is selected during logical allocation,
4935 /// with only that one child's sub-tree contributing to constraints
4936 /// aggregation.
4937 /// * false - The first parent node in common between the calling Node and
4938 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
4939 /// this means the first parent node in common is a
4940 /// BufferCollectionToken or BufferCollection (regardless of not
4941 /// Close()ed or Close()ed). This means that the calling Node and the
4942 /// node_ref Node _may_ have both their constraints apply during
4943 /// constraints aggregation of the logical allocation, if both Node(s)
4944 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
4945 /// In this case, there is no BufferCollectionTokenGroup that will
4946 /// directly prevent the two Node(s) from both being selected and their
4947 /// constraints both aggregated, but even when false, one or both
4948 /// Node(s) may still be eliminated from consideration if one or both
4949 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
4950 /// which selects a child sub-tree other than the sub-tree containing
4951 /// the calling Node or node_ref Node.
4952 pub fn r#is_alternate_for(
4953 &self,
4954 mut node_ref: fidl::Event,
4955 ) -> fidl::client::QueryResponseFut<
4956 NodeIsAlternateForResult,
4957 fidl::encoding::DefaultFuchsiaResourceDialect,
4958 > {
4959 BufferCollectionTokenProxyInterface::r#is_alternate_for(self, node_ref)
4960 }
4961
4962 /// This method can be used to add more participants prior to creating a
4963 /// shared BufferCollection. A new token will be returned for each entry in
4964 /// the `rights_attenuation_masks` array. The return value is the client
4965 /// ends of each new participant token.
4966 ///
4967 /// If the calling token may not actually be a valid token at all due to
4968 /// a potentially hostile/untrusted provider of the token, consider using
4969 /// ValidateBufferCollectionToken() first instead of potentially getting
4970 /// stuck indefinitely if DuplicateSync() never responds due to the calling
4971 /// token not being a real token.
4972 ///
4973 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
4974 /// after calling this method.
4975 ///
4976 /// All tokens must be turned in via BindSharedCollection() or Close() for a
4977 /// BufferCollection to be successfully created.
4978 ///
4979 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
4980 /// will be absent in the buffer VMO rights obtainable via the corresponding
4981 /// returned token. This allows an initiator or intermediary participant to
4982 /// attenuate the rights available to a participant. This does not allow a
4983 /// participant to gain rights that the participant doesn't already have.
4984 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
4985 /// attenuation should be applied.
4986 pub fn r#duplicate_sync(
4987 &self,
4988 mut rights_attenuation_masks: &[fidl::Rights],
4989 ) -> fidl::client::QueryResponseFut<
4990 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
4991 fidl::encoding::DefaultFuchsiaResourceDialect,
4992 > {
4993 BufferCollectionTokenProxyInterface::r#duplicate_sync(self, rights_attenuation_masks)
4994 }
4995
4996 /// This method can be used to add a participant prior to creating a shared
4997 /// BufferCollection. It should only be used instead of DuplicateSync in
4998 /// performance sensitive cases where it would be undesireable to wait for
4999 /// sysmem to respond as part of each duplicate.
5000 ///
5001 /// After sending one or more Duplicate() messages, and before sending the
5002 /// created tokens to other participants (or to other Allocator channels),
5003 /// the client should send a Sync() and wait for its response. The Sync()
5004 /// call can be made on the token, or on the BufferCollection obtained by
5005 /// passing this token to BindSharedCollection(). Either will ensure that
5006 /// the server knows about the tokens created via Duplicate() before the
5007 /// other participant sends the token to the server via separate Allocator
5008 /// channel.
5009 ///
5010 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5011 /// BufferCollection to be successfully created.
5012 ///
5013 /// When a client calls BindSharedCollection() to turn in a
5014 /// BufferCollectionToken, the server will process all Duplicate() messages
5015 /// before closing down the BufferCollectionToken. This allows the client
5016 /// to Duplicate() and immediately turn in the BufferCollectionToken using
5017 /// BindSharedCollection, then later transfer the client end of token_request
5018 /// to another participant - the server will notice the existence of the
5019 /// token_request before considering this BufferCollectionToken fully closed.
5020 ///
5021 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
5022 /// absent in the buffer VMO rights obtainable via the client end of
5023 /// token_request. This allows an initiator or intermediary participant to
5024 /// attenuate the rights available to a participant. This does not allow a
5025 /// participant to gain rights that the participant doesn't already have.
5026 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5027 /// attenuation should be applied.
5028 ///
5029 /// These values for rights_attenuation_mask result in no attenuation:
5030 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
5031 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
5032 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
5033 ///
5034 /// `token_request` is the server end of a BufferCollectionToken channel.
5035 /// The client end of this channel acts as another participant in creating the
5036 /// shared BufferCollection.
5037 pub fn r#duplicate(
5038 &self,
5039 mut rights_attenuation_mask: u32,
5040 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5041 ) -> Result<(), fidl::Error> {
5042 BufferCollectionTokenProxyInterface::r#duplicate(
5043 self,
5044 rights_attenuation_mask,
5045 token_request,
5046 )
5047 }
5048
5049 /// A dispensable token can fail after buffers are logically allocated
5050 /// without causing failure of its parent (if any).
5051 ///
5052 /// The dispensable token participates in constraints aggregation along with
5053 /// its parent before logical buffer allocation. If the dispensable token
5054 /// fails before buffers are logically allocated, the failure propagates to
5055 /// the dispensable token's parent.
5056 ///
5057 /// After buffers are logically allocated, failure of the dispensable token
5058 /// (or any child of the dispensable token) does not propagate to the
5059 /// dispensable token's parent. Failure does propagate from a normal
5060 /// child of a dispensable token to the dispensable token. Failure
5061 /// of a child is blocked from reaching its parent if the child is attached,
5062 /// or if the child is dispensable and the failure occurred after logical
5063 /// allocation.
5064 ///
5065 /// A dispensable token can be used in cases where a participant needs to
5066 /// provide constraints, but after buffers are allocated, the participant
5067 /// can fail without causing buffer collection failure from the parent's
5068 /// point of view.
5069 ///
5070 /// In contrast, AttachToken() can be used to create a token which does not
5071 /// participate in constraints aggregation with its parent, and whose
5072 /// failure at any time does not propagate to its parent, and whose delay
5073 /// providing constraints does not prevent the parent from completing its
5074 /// buffer allocation.
5075 ///
5076 /// An initiator may in some scenarios choose to initially use a dispensable
5077 /// token for a given instance of a participant, and then later if the first
5078 /// instance of that participant fails, a new second instance of that
5079 /// participant my be given a token created with AttachToken().
5080 ///
5081 /// If a client uses this message, the client should not rely on the
5082 /// client's own BufferCollectionToken or BufferCollection channel to close
5083 /// from the server end due to abrupt failure of any BufferCollectionToken
5084 /// or BufferCollection that the client has SetDispensable() and given out
5085 /// to another process. For this reason, the client should take extra care
5086 /// to notice failure of that other process via other means.
5087 ///
5088 /// While it is possible (and potentially useful) to SetDispensable() on a
5089 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
5090 /// replace a failed dispensable token that was a direct child of a group
5091 /// with a new token using AttachToken() (since there's no AttachToken() on
5092 /// a group). Instead, to enable AttachToken() replacement in this case,
5093 /// create an additional non-dispensable token (node) that's a direct child
5094 /// of the group and make the existing dispensable token a child of the
5095 /// additional token (node). This way, the additional token (node) that is
5096 /// a direct child of the group has BufferCollection.AttachToken() which can
5097 /// be used to replace the failed dispensable token.
5098 ///
5099 /// SetDispensable() on an already-dispensable token is idempotent.
5100 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
5101 BufferCollectionTokenProxyInterface::r#set_dispensable(self)
5102 }
5103
5104 /// Most sysmem clients and many participants don't need to care about this
5105 /// message or about BufferCollectionTokenGroup(s) in general.
5106 ///
5107 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
5108 /// tokens. The child tokens which are not selected during aggregation will
5109 /// fail (close), which a potential participant should notice when their
5110 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
5111 /// participant to clean up the speculative usage that didn't end up
5112 /// happening (similarly to a normal BufferCollection server end closing
5113 /// on failure of a logical buffer collection).
5114 ///
5115 /// See comments on protocol BufferCollectionTokenGroup.
5116 ///
5117 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
5118 /// applied to the whole group can be achieved with a token for this purpose
5119 /// as a direct parent of the group.
5120 ///
5121 /// group_request - the server end of a BufferCollectionTokenGroup channel
5122 /// to be served by sysmem.
5123 pub fn r#create_buffer_collection_token_group(
5124 &self,
5125 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
5126 ) -> Result<(), fidl::Error> {
5127 BufferCollectionTokenProxyInterface::r#create_buffer_collection_token_group(
5128 self,
5129 group_request,
5130 )
5131 }
5132}
5133
5134impl BufferCollectionTokenProxyInterface for BufferCollectionTokenProxy {
5135 type SyncResponseFut =
5136 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
5137 fn r#sync(&self) -> Self::SyncResponseFut {
5138 fn _decode(
5139 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5140 ) -> Result<(), fidl::Error> {
5141 let _response = fidl::client::decode_transaction_body::<
5142 fidl::encoding::EmptyPayload,
5143 fidl::encoding::DefaultFuchsiaResourceDialect,
5144 0x4577e238ae26291,
5145 >(_buf?)?;
5146 Ok(_response)
5147 }
5148 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
5149 (),
5150 0x4577e238ae26291,
5151 fidl::encoding::DynamicFlags::empty(),
5152 _decode,
5153 )
5154 }
5155
5156 fn r#close(&self) -> Result<(), fidl::Error> {
5157 self.client.send::<fidl::encoding::EmptyPayload>(
5158 (),
5159 0x5b1d7a4f5681fca7,
5160 fidl::encoding::DynamicFlags::empty(),
5161 )
5162 }
5163
5164 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
5165 self.client.send::<NodeSetNameRequest>(
5166 (priority, name),
5167 0x77a41bb6217e2443,
5168 fidl::encoding::DynamicFlags::empty(),
5169 )
5170 }
5171
5172 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
5173 self.client.send::<NodeSetDebugClientInfoRequest>(
5174 (name, id),
5175 0x7275759070eb5ee2,
5176 fidl::encoding::DynamicFlags::empty(),
5177 )
5178 }
5179
5180 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
5181 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
5182 (deadline,),
5183 0x46d38f4772638867,
5184 fidl::encoding::DynamicFlags::empty(),
5185 )
5186 }
5187
5188 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
5189 self.client.send::<fidl::encoding::EmptyPayload>(
5190 (),
5191 0x6bfbe2cf1701d288,
5192 fidl::encoding::DynamicFlags::empty(),
5193 )
5194 }
5195
5196 type GetNodeRefResponseFut =
5197 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
5198 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
5199 fn _decode(
5200 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5201 ) -> Result<fidl::Event, fidl::Error> {
5202 let _response = fidl::client::decode_transaction_body::<
5203 NodeGetNodeRefResponse,
5204 fidl::encoding::DefaultFuchsiaResourceDialect,
5205 0x467b7c75c35c3b84,
5206 >(_buf?)?;
5207 Ok(_response.node_ref)
5208 }
5209 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
5210 (),
5211 0x467b7c75c35c3b84,
5212 fidl::encoding::DynamicFlags::empty(),
5213 _decode,
5214 )
5215 }
5216
5217 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
5218 NodeIsAlternateForResult,
5219 fidl::encoding::DefaultFuchsiaResourceDialect,
5220 >;
5221 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
5222 fn _decode(
5223 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5224 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
5225 let _response = fidl::client::decode_transaction_body::<
5226 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
5227 fidl::encoding::DefaultFuchsiaResourceDialect,
5228 0x33a2a7aff2776c07,
5229 >(_buf?)?;
5230 Ok(_response.map(|x| x.is_alternate))
5231 }
5232 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
5233 (node_ref,),
5234 0x33a2a7aff2776c07,
5235 fidl::encoding::DynamicFlags::empty(),
5236 _decode,
5237 )
5238 }
5239
5240 type DuplicateSyncResponseFut = fidl::client::QueryResponseFut<
5241 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
5242 fidl::encoding::DefaultFuchsiaResourceDialect,
5243 >;
5244 fn r#duplicate_sync(
5245 &self,
5246 mut rights_attenuation_masks: &[fidl::Rights],
5247 ) -> Self::DuplicateSyncResponseFut {
5248 fn _decode(
5249 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5250 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error>
5251 {
5252 let _response = fidl::client::decode_transaction_body::<
5253 BufferCollectionTokenDuplicateSyncResponse,
5254 fidl::encoding::DefaultFuchsiaResourceDialect,
5255 0x49ed7ab7cc19f18,
5256 >(_buf?)?;
5257 Ok(_response.tokens)
5258 }
5259 self.client.send_query_and_decode::<
5260 BufferCollectionTokenDuplicateSyncRequest,
5261 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
5262 >(
5263 (rights_attenuation_masks,),
5264 0x49ed7ab7cc19f18,
5265 fidl::encoding::DynamicFlags::empty(),
5266 _decode,
5267 )
5268 }
5269
5270 fn r#duplicate(
5271 &self,
5272 mut rights_attenuation_mask: u32,
5273 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5274 ) -> Result<(), fidl::Error> {
5275 self.client.send::<BufferCollectionTokenDuplicateRequest>(
5276 (rights_attenuation_mask, token_request),
5277 0x2f9f81bdde4b7292,
5278 fidl::encoding::DynamicFlags::empty(),
5279 )
5280 }
5281
5282 fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
5283 self.client.send::<fidl::encoding::EmptyPayload>(
5284 (),
5285 0x76e4ec34fc2cf5b3,
5286 fidl::encoding::DynamicFlags::empty(),
5287 )
5288 }
5289
5290 fn r#create_buffer_collection_token_group(
5291 &self,
5292 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
5293 ) -> Result<(), fidl::Error> {
5294 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
5295 (group_request,),
5296 0x2f6243e05f22b9a7,
5297 fidl::encoding::DynamicFlags::empty(),
5298 )
5299 }
5300}
5301
5302pub struct BufferCollectionTokenEventStream {
5303 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
5304}
5305
5306impl std::marker::Unpin for BufferCollectionTokenEventStream {}
5307
5308impl futures::stream::FusedStream for BufferCollectionTokenEventStream {
5309 fn is_terminated(&self) -> bool {
5310 self.event_receiver.is_terminated()
5311 }
5312}
5313
5314impl futures::Stream for BufferCollectionTokenEventStream {
5315 type Item = Result<BufferCollectionTokenEvent, fidl::Error>;
5316
5317 fn poll_next(
5318 mut self: std::pin::Pin<&mut Self>,
5319 cx: &mut std::task::Context<'_>,
5320 ) -> std::task::Poll<Option<Self::Item>> {
5321 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
5322 &mut self.event_receiver,
5323 cx
5324 )?) {
5325 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenEvent::decode(buf))),
5326 None => std::task::Poll::Ready(None),
5327 }
5328 }
5329}
5330
5331#[derive(Debug)]
5332pub enum BufferCollectionTokenEvent {}
5333
5334impl BufferCollectionTokenEvent {
5335 /// Decodes a message buffer as a [`BufferCollectionTokenEvent`].
5336 fn decode(
5337 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
5338 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
5339 let (bytes, _handles) = buf.split_mut();
5340 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
5341 debug_assert_eq!(tx_header.tx_id, 0);
5342 match tx_header.ordinal {
5343 _ => Err(fidl::Error::UnknownOrdinal {
5344 ordinal: tx_header.ordinal,
5345 protocol_name:
5346 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
5347 }),
5348 }
5349 }
5350}
5351
5352/// A Stream of incoming requests for fuchsia.sysmem/BufferCollectionToken.
5353pub struct BufferCollectionTokenRequestStream {
5354 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
5355 is_terminated: bool,
5356}
5357
5358impl std::marker::Unpin for BufferCollectionTokenRequestStream {}
5359
5360impl futures::stream::FusedStream for BufferCollectionTokenRequestStream {
5361 fn is_terminated(&self) -> bool {
5362 self.is_terminated
5363 }
5364}
5365
5366impl fidl::endpoints::RequestStream for BufferCollectionTokenRequestStream {
5367 type Protocol = BufferCollectionTokenMarker;
5368 type ControlHandle = BufferCollectionTokenControlHandle;
5369
5370 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
5371 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
5372 }
5373
5374 fn control_handle(&self) -> Self::ControlHandle {
5375 BufferCollectionTokenControlHandle { inner: self.inner.clone() }
5376 }
5377
5378 fn into_inner(
5379 self,
5380 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
5381 {
5382 (self.inner, self.is_terminated)
5383 }
5384
5385 fn from_inner(
5386 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
5387 is_terminated: bool,
5388 ) -> Self {
5389 Self { inner, is_terminated }
5390 }
5391}
5392
5393impl futures::Stream for BufferCollectionTokenRequestStream {
5394 type Item = Result<BufferCollectionTokenRequest, fidl::Error>;
5395
5396 fn poll_next(
5397 mut self: std::pin::Pin<&mut Self>,
5398 cx: &mut std::task::Context<'_>,
5399 ) -> std::task::Poll<Option<Self::Item>> {
5400 let this = &mut *self;
5401 if this.inner.check_shutdown(cx) {
5402 this.is_terminated = true;
5403 return std::task::Poll::Ready(None);
5404 }
5405 if this.is_terminated {
5406 panic!("polled BufferCollectionTokenRequestStream after completion");
5407 }
5408 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
5409 |bytes, handles| {
5410 match this.inner.channel().read_etc(cx, bytes, handles) {
5411 std::task::Poll::Ready(Ok(())) => {}
5412 std::task::Poll::Pending => return std::task::Poll::Pending,
5413 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
5414 this.is_terminated = true;
5415 return std::task::Poll::Ready(None);
5416 }
5417 std::task::Poll::Ready(Err(e)) => {
5418 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
5419 e.into(),
5420 ))));
5421 }
5422 }
5423
5424 // A message has been received from the channel
5425 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
5426
5427 std::task::Poll::Ready(Some(match header.ordinal {
5428 0x4577e238ae26291 => {
5429 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5430 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5431 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5432 let control_handle = BufferCollectionTokenControlHandle {
5433 inner: this.inner.clone(),
5434 };
5435 Ok(BufferCollectionTokenRequest::Sync {
5436 responder: BufferCollectionTokenSyncResponder {
5437 control_handle: std::mem::ManuallyDrop::new(control_handle),
5438 tx_id: header.tx_id,
5439 },
5440 })
5441 }
5442 0x5b1d7a4f5681fca7 => {
5443 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5444 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5445 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5446 let control_handle = BufferCollectionTokenControlHandle {
5447 inner: this.inner.clone(),
5448 };
5449 Ok(BufferCollectionTokenRequest::Close {
5450 control_handle,
5451 })
5452 }
5453 0x77a41bb6217e2443 => {
5454 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5455 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5456 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
5457 let control_handle = BufferCollectionTokenControlHandle {
5458 inner: this.inner.clone(),
5459 };
5460 Ok(BufferCollectionTokenRequest::SetName {priority: req.priority,
5461name: req.name,
5462
5463 control_handle,
5464 })
5465 }
5466 0x7275759070eb5ee2 => {
5467 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5468 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5469 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
5470 let control_handle = BufferCollectionTokenControlHandle {
5471 inner: this.inner.clone(),
5472 };
5473 Ok(BufferCollectionTokenRequest::SetDebugClientInfo {name: req.name,
5474id: req.id,
5475
5476 control_handle,
5477 })
5478 }
5479 0x46d38f4772638867 => {
5480 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5481 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5482 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
5483 let control_handle = BufferCollectionTokenControlHandle {
5484 inner: this.inner.clone(),
5485 };
5486 Ok(BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {deadline: req.deadline,
5487
5488 control_handle,
5489 })
5490 }
5491 0x6bfbe2cf1701d288 => {
5492 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5493 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5494 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5495 let control_handle = BufferCollectionTokenControlHandle {
5496 inner: this.inner.clone(),
5497 };
5498 Ok(BufferCollectionTokenRequest::SetVerboseLogging {
5499 control_handle,
5500 })
5501 }
5502 0x467b7c75c35c3b84 => {
5503 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5504 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5505 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5506 let control_handle = BufferCollectionTokenControlHandle {
5507 inner: this.inner.clone(),
5508 };
5509 Ok(BufferCollectionTokenRequest::GetNodeRef {
5510 responder: BufferCollectionTokenGetNodeRefResponder {
5511 control_handle: std::mem::ManuallyDrop::new(control_handle),
5512 tx_id: header.tx_id,
5513 },
5514 })
5515 }
5516 0x33a2a7aff2776c07 => {
5517 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5518 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5519 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
5520 let control_handle = BufferCollectionTokenControlHandle {
5521 inner: this.inner.clone(),
5522 };
5523 Ok(BufferCollectionTokenRequest::IsAlternateFor {node_ref: req.node_ref,
5524
5525 responder: BufferCollectionTokenIsAlternateForResponder {
5526 control_handle: std::mem::ManuallyDrop::new(control_handle),
5527 tx_id: header.tx_id,
5528 },
5529 })
5530 }
5531 0x49ed7ab7cc19f18 => {
5532 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5533 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5534 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateSyncRequest>(&header, _body_bytes, handles, &mut req)?;
5535 let control_handle = BufferCollectionTokenControlHandle {
5536 inner: this.inner.clone(),
5537 };
5538 Ok(BufferCollectionTokenRequest::DuplicateSync {rights_attenuation_masks: req.rights_attenuation_masks,
5539
5540 responder: BufferCollectionTokenDuplicateSyncResponder {
5541 control_handle: std::mem::ManuallyDrop::new(control_handle),
5542 tx_id: header.tx_id,
5543 },
5544 })
5545 }
5546 0x2f9f81bdde4b7292 => {
5547 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5548 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5549 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateRequest>(&header, _body_bytes, handles, &mut req)?;
5550 let control_handle = BufferCollectionTokenControlHandle {
5551 inner: this.inner.clone(),
5552 };
5553 Ok(BufferCollectionTokenRequest::Duplicate {rights_attenuation_mask: req.rights_attenuation_mask,
5554token_request: req.token_request,
5555
5556 control_handle,
5557 })
5558 }
5559 0x76e4ec34fc2cf5b3 => {
5560 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5561 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5562 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5563 let control_handle = BufferCollectionTokenControlHandle {
5564 inner: this.inner.clone(),
5565 };
5566 Ok(BufferCollectionTokenRequest::SetDispensable {
5567 control_handle,
5568 })
5569 }
5570 0x2f6243e05f22b9a7 => {
5571 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5572 let mut req = fidl::new_empty!(BufferCollectionTokenCreateBufferCollectionTokenGroupRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5573 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(&header, _body_bytes, handles, &mut req)?;
5574 let control_handle = BufferCollectionTokenControlHandle {
5575 inner: this.inner.clone(),
5576 };
5577 Ok(BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {group_request: req.group_request,
5578
5579 control_handle,
5580 })
5581 }
5582 _ => Err(fidl::Error::UnknownOrdinal {
5583 ordinal: header.ordinal,
5584 protocol_name: <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
5585 }),
5586 }))
5587 },
5588 )
5589 }
5590}
5591
5592/// A BufferCollectionToken is not a BufferCollection, but rather a way to
5593/// identify a potential shared BufferCollection prior to the BufferCollection
5594/// being allocated.
5595///
5596/// We use a channel for the BufferCollectionToken instead of a single eventpair
5597/// (pair) because this way we can detect error conditions like a participant
5598/// dying mid-create.
5599///
5600/// The fuchsia.sysmem.BufferCollectionToken type is not yet deprecated due to
5601/// its use in some other protocols (for now), but all the internals of
5602/// fuchsia.sysmem.BufferCollectionToken are deprecated. Token channels serve
5603/// both fuchsia.sysmem.BufferCollectionToken and
5604/// fuchsia.sysmem2.BufferCollectionToken.
5605///
5606/// This protocol will be deprecated once other protocols have switched their
5607/// token fields to fuchsia.sysmem2.BufferCollectionToken.
5608#[derive(Debug)]
5609pub enum BufferCollectionTokenRequest {
5610 /// Ensure that previous messages, including Duplicate() messages on a
5611 /// token, collection, or group, have been received server side.
5612 ///
5613 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
5614 /// valid sysmem token risks the Sync() hanging forever. See
5615 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
5616 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
5617 /// Another way is to pass the token to BindSharedCollection(), which also
5618 /// validates the token as part of exchanging it for a BufferCollection
5619 /// channel, and BufferCollection Sync() can then be used.
5620 ///
5621 /// After a Sync(), it's then safe to send the client end of token_request
5622 /// to another participant knowing the server will recognize the token when
5623 /// it's sent into BindSharedCollection() by the other participant.
5624 ///
5625 /// Other options include waiting for each token.Duplicate() to complete
5626 /// individually (using separate call to token.Sync() after each), or
5627 /// calling Sync() on BufferCollection after the token has been turned in
5628 /// via BindSharedCollection().
5629 ///
5630 /// Another way to mitigate is to avoid calling Sync() on the token, and
5631 /// instead later deal with potential failure of BufferCollection.Sync() if
5632 /// the original token was invalid. This option can be preferable from a
5633 /// performance point of view, but requires client code to delay sending
5634 /// tokens duplicated from this token until after client code has converted
5635 /// the duplicating token to a BufferCollection and received successful
5636 /// response from BufferCollection.Sync().
5637 ///
5638 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
5639 /// When BufferCollection.Sync() isn't feasible, the caller must already
5640 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
5641 /// hang forever. See ValidateBufferCollectionToken() to check token
5642 /// validity first if the token isn't already known to be (is/was) valid.
5643 Sync { responder: BufferCollectionTokenSyncResponder },
5644 /// On a BufferCollectionToken channel:
5645 ///
5646 /// Normally a participant will convert a BufferCollectionToken into a
5647 /// BufferCollection view, but a participant is also free to Close() the
5648 /// token (and then close the channel immediately or shortly later in
5649 /// response to server closing its end), which avoids causing logical buffer
5650 /// collection failure. Â Normally an unexpected token channel close will
5651 /// cause logical buffer collection failure (the only exceptions being
5652 /// certain cases involving AttachToken() or SetDispensable()).
5653 ///
5654 /// On a BufferCollection channel:
5655 ///
5656 /// By default the server handles unexpected failure of a BufferCollection
5657 /// by failing the whole logical buffer collection. Partly this is to
5658 /// expedite closing VMO handles to reclaim memory when any participant
5659 /// fails. If a participant would like to cleanly close a BufferCollection
5660 /// view without causing logical buffer collection failure, the participant
5661 /// can send Close() before closing the client end of the BufferCollection
5662 /// channel. If this is the last BufferCollection view, the logical buffer
5663 /// collection will still go away. The Close() can occur before or after
5664 /// SetConstraints(). If before SetConstraints(), the buffer collection
5665 /// won't require constraints from this node in order to allocate. If
5666 /// after SetConstraints(), the constraints are retained and aggregated
5667 /// along with any subsequent logical allocation(s), despite the lack of
5668 /// channel connection.
5669 ///
5670 /// On a BufferCollectionTokenGroup channel:
5671 ///
5672 /// By default, unexpected failure of a BufferCollectionTokenGroup will
5673 /// trigger failure of the logical BufferCollectionTokenGroup and will
5674 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
5675 /// channel without failing the logical group or propagating failure, send
5676 /// Close() before closing the channel client endpoint.
5677 ///
5678 /// If Close() occurs before AllChildrenPresent(), the logical buffer
5679 /// collection will still fail despite the Close() (because sysmem can't be
5680 /// sure whether all relevant children were created, so it's ambiguous
5681 /// whether all relevant constraints will be provided to sysmem). If
5682 /// Close() occurs after AllChildrenPresent(), the children and all their
5683 /// constraints remain intact (just as they would if the
5684 /// BufferCollectionTokenGroup channel had remained open), and the close
5685 /// doesn't trigger or propagate failure.
5686 Close { control_handle: BufferCollectionTokenControlHandle },
5687 /// Set a name for VMOs in this buffer collection. The name may be truncated
5688 /// shorter. The name only affects VMOs allocated after it's set - this call
5689 /// does not rename existing VMOs. If multiple clients set different names
5690 /// then the larger priority value will win.
5691 SetName { priority: u32, name: String, control_handle: BufferCollectionTokenControlHandle },
5692 /// Set information about the current client that can be used by sysmem to
5693 /// help debug leaking memory and hangs waiting for constraints. |name| can
5694 /// be an arbitrary string, but the current process name (see
5695 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
5696 /// arbitrary id, but the current process ID (see
5697 /// fsl::GetCurrentProcessKoid()) is a good default.
5698 ///
5699 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
5700 /// indicate which client is closing their channel first, leading to
5701 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
5702 /// over, but if happening earlier than expected, the
5703 /// client-channel-specific name can help diagnose where the failure is
5704 /// first coming from, from sysmem's point of view).
5705 ///
5706 /// By default (unless overriden by this message or using
5707 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
5708 /// parent Node at the time the child Node is created. While this can be
5709 /// better than nothing, it's often better for each participant to use
5710 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
5711 /// info directly relevant to the current client. Also, SetVerboseLogging()
5712 /// can be used to help disambiguate if a Node is suspected of having info
5713 /// that was copied from its parent.
5714 SetDebugClientInfo { name: String, id: u64, control_handle: BufferCollectionTokenControlHandle },
5715 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
5716 /// after creating a collection. Clients can call this method to change
5717 /// when the log is printed. If multiple client set the deadline, it's
5718 /// unspecified which deadline will take effect.
5719 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: BufferCollectionTokenControlHandle },
5720 /// Verbose logging includes constraints set via SetConstraints() from each
5721 /// client along with info set via SetDebugClientInfo() and the structure of
5722 /// the tree of Node(s).
5723 ///
5724 /// Normally sysmem prints only a single line complaint when aggregation
5725 /// fails, with just the specific detailed reason that aggregation failed,
5726 /// with minimal context. While this is often enough to diagnose a problem
5727 /// if only a small change was made and the system had been working before
5728 /// the small change, it's often not particularly helpful for getting a new
5729 /// buffer collection to work for the first time. Especially with more
5730 /// complex trees of nodes, involving things like AttachToken(),
5731 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
5732 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
5733 /// looks like and why it's failing a logical allocation, or why a tree or
5734 /// sub-tree is failing sooner than expected.
5735 ///
5736 /// The intent of the extra logging is to be acceptable from a performance
5737 /// point of view, if only enabled on a low number of buffer collections.
5738 /// If we're not tracking down a bug, we shouldn't send this message.
5739 ///
5740 /// If too many participants leave verbose logging enabled, we may end up
5741 /// needing to require that system-wide sysmem verbose logging be permitted
5742 /// via some other setting, to avoid sysmem spamming the log too much due to
5743 /// this message.
5744 ///
5745 /// This may be a NOP for some nodes due to intentional policy associated
5746 /// with the node, if we don't trust a node enough to let it turn on verbose
5747 /// logging.
5748 SetVerboseLogging { control_handle: BufferCollectionTokenControlHandle },
5749 /// This gets an event handle that can be used as a parameter to
5750 /// IsAlternateFor() called on any Node. The client will not be granted the
5751 /// right to signal this event, as this handle should only be used as proof
5752 /// that the client obtained this handle from this Node.
5753 ///
5754 /// Because this is a get not a set, no Sync() is needed between the
5755 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
5756 /// potentially being on different channels.
5757 ///
5758 /// See also IsAlternateFor().
5759 GetNodeRef { responder: BufferCollectionTokenGetNodeRefResponder },
5760 /// This checks whether the calling node is in a subtree rooted at a
5761 /// different child token of a common parent BufferCollectionTokenGroup, in
5762 /// relation to the passed-in node_ref.
5763 ///
5764 /// This call is for assisting with admission control de-duplication, and
5765 /// with debugging.
5766 ///
5767 /// The node_ref must be obtained using GetNodeRef() of a
5768 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
5769 ///
5770 /// The node_ref can be a duplicated handle; it's not necessary to call
5771 /// GetNodeRef() for every call to IsAlternateFor().
5772 ///
5773 /// If a calling token may not actually be a valid token at all due to
5774 /// a potentially hostile/untrusted provider of the token, call
5775 /// ValidateBufferCollectionToken() first instead of potentially getting
5776 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
5777 /// token not being a real token (not really talking to sysmem). Another
5778 /// option is to call BindSharedCollection with this token first which also
5779 /// validates the token along with converting it to a BufferCollection, then
5780 /// call BufferCollection IsAlternateFor().
5781 ///
5782 /// error values:
5783 ///
5784 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
5785 /// buffer collection as the calling Node. Before logical allocation and
5786 /// within the same logical allocation sub-tree, this essentially means that
5787 /// the node_ref was never part of this logical buffer collection, since
5788 /// before logical allocation all node_refs that come into existence remain
5789 /// in existence at least until logical allocation (including Node(s) that
5790 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
5791 /// to be returned, this Node's channel needs to still be connected server
5792 /// side, which won't be the case if the whole logical allocation has
5793 /// failed. After logical allocation or in a different logical allocation
5794 /// sub-tree there are additional potential reasons for this error. For
5795 /// example a different logical allocation (separated from this Node(s)
5796 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
5797 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
5798 /// exist and may select a different child sub-tree than the sub-tree the
5799 /// node_ref is in causing deletion of the node_ref Node. The only time
5800 /// sysmem keeps a Node around after that Node has no corresponding channel
5801 /// is when Close() is used and the Node's sub-tree has not yet failed.
5802 /// Another reason for this error is if the node_ref is an eventpair handle
5803 /// with sufficient rights, but isn't actually a real node_ref obtained from
5804 /// GetNodeRef().
5805 ///
5806 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
5807 /// eventpair handle, or doesn't have the needed rights expected on a real
5808 /// node_ref.
5809 ///
5810 /// No other failing status codes are returned by this call. However,
5811 /// sysmem may add additional codes in future, so the client should have
5812 /// sensible default handling for any failing status code.
5813 ///
5814 /// On success, is_alternate has the following meaning:
5815 /// * true - The first parent node in common between the calling node and
5816 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
5817 /// the calling Node and the node_ref Node will _not_ have both their
5818 /// constraints apply - rather sysmem will choose one or the other of
5819 /// the constraints - never both. This is because only one child of
5820 /// a BufferCollectionTokenGroup is selected during logical allocation,
5821 /// with only that one child's sub-tree contributing to constraints
5822 /// aggregation.
5823 /// * false - The first parent node in common between the calling Node and
5824 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
5825 /// this means the first parent node in common is a
5826 /// BufferCollectionToken or BufferCollection (regardless of not
5827 /// Close()ed or Close()ed). This means that the calling Node and the
5828 /// node_ref Node _may_ have both their constraints apply during
5829 /// constraints aggregation of the logical allocation, if both Node(s)
5830 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
5831 /// In this case, there is no BufferCollectionTokenGroup that will
5832 /// directly prevent the two Node(s) from both being selected and their
5833 /// constraints both aggregated, but even when false, one or both
5834 /// Node(s) may still be eliminated from consideration if one or both
5835 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
5836 /// which selects a child sub-tree other than the sub-tree containing
5837 /// the calling Node or node_ref Node.
5838 IsAlternateFor {
5839 node_ref: fidl::Event,
5840 responder: BufferCollectionTokenIsAlternateForResponder,
5841 },
5842 /// This method can be used to add more participants prior to creating a
5843 /// shared BufferCollection. A new token will be returned for each entry in
5844 /// the `rights_attenuation_masks` array. The return value is the client
5845 /// ends of each new participant token.
5846 ///
5847 /// If the calling token may not actually be a valid token at all due to
5848 /// a potentially hostile/untrusted provider of the token, consider using
5849 /// ValidateBufferCollectionToken() first instead of potentially getting
5850 /// stuck indefinitely if DuplicateSync() never responds due to the calling
5851 /// token not being a real token.
5852 ///
5853 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
5854 /// after calling this method.
5855 ///
5856 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5857 /// BufferCollection to be successfully created.
5858 ///
5859 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
5860 /// will be absent in the buffer VMO rights obtainable via the corresponding
5861 /// returned token. This allows an initiator or intermediary participant to
5862 /// attenuate the rights available to a participant. This does not allow a
5863 /// participant to gain rights that the participant doesn't already have.
5864 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5865 /// attenuation should be applied.
5866 DuplicateSync {
5867 rights_attenuation_masks: Vec<fidl::Rights>,
5868 responder: BufferCollectionTokenDuplicateSyncResponder,
5869 },
5870 /// This method can be used to add a participant prior to creating a shared
5871 /// BufferCollection. It should only be used instead of DuplicateSync in
5872 /// performance sensitive cases where it would be undesireable to wait for
5873 /// sysmem to respond as part of each duplicate.
5874 ///
5875 /// After sending one or more Duplicate() messages, and before sending the
5876 /// created tokens to other participants (or to other Allocator channels),
5877 /// the client should send a Sync() and wait for its response. The Sync()
5878 /// call can be made on the token, or on the BufferCollection obtained by
5879 /// passing this token to BindSharedCollection(). Either will ensure that
5880 /// the server knows about the tokens created via Duplicate() before the
5881 /// other participant sends the token to the server via separate Allocator
5882 /// channel.
5883 ///
5884 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5885 /// BufferCollection to be successfully created.
5886 ///
5887 /// When a client calls BindSharedCollection() to turn in a
5888 /// BufferCollectionToken, the server will process all Duplicate() messages
5889 /// before closing down the BufferCollectionToken. This allows the client
5890 /// to Duplicate() and immediately turn in the BufferCollectionToken using
5891 /// BindSharedCollection, then later transfer the client end of token_request
5892 /// to another participant - the server will notice the existence of the
5893 /// token_request before considering this BufferCollectionToken fully closed.
5894 ///
5895 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
5896 /// absent in the buffer VMO rights obtainable via the client end of
5897 /// token_request. This allows an initiator or intermediary participant to
5898 /// attenuate the rights available to a participant. This does not allow a
5899 /// participant to gain rights that the participant doesn't already have.
5900 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5901 /// attenuation should be applied.
5902 ///
5903 /// These values for rights_attenuation_mask result in no attenuation:
5904 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
5905 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
5906 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
5907 ///
5908 /// `token_request` is the server end of a BufferCollectionToken channel.
5909 /// The client end of this channel acts as another participant in creating the
5910 /// shared BufferCollection.
5911 Duplicate {
5912 rights_attenuation_mask: u32,
5913 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5914 control_handle: BufferCollectionTokenControlHandle,
5915 },
5916 /// A dispensable token can fail after buffers are logically allocated
5917 /// without causing failure of its parent (if any).
5918 ///
5919 /// The dispensable token participates in constraints aggregation along with
5920 /// its parent before logical buffer allocation. If the dispensable token
5921 /// fails before buffers are logically allocated, the failure propagates to
5922 /// the dispensable token's parent.
5923 ///
5924 /// After buffers are logically allocated, failure of the dispensable token
5925 /// (or any child of the dispensable token) does not propagate to the
5926 /// dispensable token's parent. Failure does propagate from a normal
5927 /// child of a dispensable token to the dispensable token. Failure
5928 /// of a child is blocked from reaching its parent if the child is attached,
5929 /// or if the child is dispensable and the failure occurred after logical
5930 /// allocation.
5931 ///
5932 /// A dispensable token can be used in cases where a participant needs to
5933 /// provide constraints, but after buffers are allocated, the participant
5934 /// can fail without causing buffer collection failure from the parent's
5935 /// point of view.
5936 ///
5937 /// In contrast, AttachToken() can be used to create a token which does not
5938 /// participate in constraints aggregation with its parent, and whose
5939 /// failure at any time does not propagate to its parent, and whose delay
5940 /// providing constraints does not prevent the parent from completing its
5941 /// buffer allocation.
5942 ///
5943 /// An initiator may in some scenarios choose to initially use a dispensable
5944 /// token for a given instance of a participant, and then later if the first
5945 /// instance of that participant fails, a new second instance of that
5946 /// participant my be given a token created with AttachToken().
5947 ///
5948 /// If a client uses this message, the client should not rely on the
5949 /// client's own BufferCollectionToken or BufferCollection channel to close
5950 /// from the server end due to abrupt failure of any BufferCollectionToken
5951 /// or BufferCollection that the client has SetDispensable() and given out
5952 /// to another process. For this reason, the client should take extra care
5953 /// to notice failure of that other process via other means.
5954 ///
5955 /// While it is possible (and potentially useful) to SetDispensable() on a
5956 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
5957 /// replace a failed dispensable token that was a direct child of a group
5958 /// with a new token using AttachToken() (since there's no AttachToken() on
5959 /// a group). Instead, to enable AttachToken() replacement in this case,
5960 /// create an additional non-dispensable token (node) that's a direct child
5961 /// of the group and make the existing dispensable token a child of the
5962 /// additional token (node). This way, the additional token (node) that is
5963 /// a direct child of the group has BufferCollection.AttachToken() which can
5964 /// be used to replace the failed dispensable token.
5965 ///
5966 /// SetDispensable() on an already-dispensable token is idempotent.
5967 SetDispensable { control_handle: BufferCollectionTokenControlHandle },
5968 /// Most sysmem clients and many participants don't need to care about this
5969 /// message or about BufferCollectionTokenGroup(s) in general.
5970 ///
5971 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
5972 /// tokens. The child tokens which are not selected during aggregation will
5973 /// fail (close), which a potential participant should notice when their
5974 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
5975 /// participant to clean up the speculative usage that didn't end up
5976 /// happening (similarly to a normal BufferCollection server end closing
5977 /// on failure of a logical buffer collection).
5978 ///
5979 /// See comments on protocol BufferCollectionTokenGroup.
5980 ///
5981 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
5982 /// applied to the whole group can be achieved with a token for this purpose
5983 /// as a direct parent of the group.
5984 ///
5985 /// group_request - the server end of a BufferCollectionTokenGroup channel
5986 /// to be served by sysmem.
5987 CreateBufferCollectionTokenGroup {
5988 group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
5989 control_handle: BufferCollectionTokenControlHandle,
5990 },
5991}
5992
5993impl BufferCollectionTokenRequest {
5994 #[allow(irrefutable_let_patterns)]
5995 pub fn into_sync(self) -> Option<(BufferCollectionTokenSyncResponder)> {
5996 if let BufferCollectionTokenRequest::Sync { responder } = self {
5997 Some((responder))
5998 } else {
5999 None
6000 }
6001 }
6002
6003 #[allow(irrefutable_let_patterns)]
6004 pub fn into_close(self) -> Option<(BufferCollectionTokenControlHandle)> {
6005 if let BufferCollectionTokenRequest::Close { control_handle } = self {
6006 Some((control_handle))
6007 } else {
6008 None
6009 }
6010 }
6011
6012 #[allow(irrefutable_let_patterns)]
6013 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionTokenControlHandle)> {
6014 if let BufferCollectionTokenRequest::SetName { priority, name, control_handle } = self {
6015 Some((priority, name, control_handle))
6016 } else {
6017 None
6018 }
6019 }
6020
6021 #[allow(irrefutable_let_patterns)]
6022 pub fn into_set_debug_client_info(
6023 self,
6024 ) -> Option<(String, u64, BufferCollectionTokenControlHandle)> {
6025 if let BufferCollectionTokenRequest::SetDebugClientInfo { name, id, control_handle } = self
6026 {
6027 Some((name, id, control_handle))
6028 } else {
6029 None
6030 }
6031 }
6032
6033 #[allow(irrefutable_let_patterns)]
6034 pub fn into_set_debug_timeout_log_deadline(
6035 self,
6036 ) -> Option<(i64, BufferCollectionTokenControlHandle)> {
6037 if let BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {
6038 deadline,
6039 control_handle,
6040 } = self
6041 {
6042 Some((deadline, control_handle))
6043 } else {
6044 None
6045 }
6046 }
6047
6048 #[allow(irrefutable_let_patterns)]
6049 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenControlHandle)> {
6050 if let BufferCollectionTokenRequest::SetVerboseLogging { control_handle } = self {
6051 Some((control_handle))
6052 } else {
6053 None
6054 }
6055 }
6056
6057 #[allow(irrefutable_let_patterns)]
6058 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGetNodeRefResponder)> {
6059 if let BufferCollectionTokenRequest::GetNodeRef { responder } = self {
6060 Some((responder))
6061 } else {
6062 None
6063 }
6064 }
6065
6066 #[allow(irrefutable_let_patterns)]
6067 pub fn into_is_alternate_for(
6068 self,
6069 ) -> Option<(fidl::Event, BufferCollectionTokenIsAlternateForResponder)> {
6070 if let BufferCollectionTokenRequest::IsAlternateFor { node_ref, responder } = self {
6071 Some((node_ref, responder))
6072 } else {
6073 None
6074 }
6075 }
6076
6077 #[allow(irrefutable_let_patterns)]
6078 pub fn into_duplicate_sync(
6079 self,
6080 ) -> Option<(Vec<fidl::Rights>, BufferCollectionTokenDuplicateSyncResponder)> {
6081 if let BufferCollectionTokenRequest::DuplicateSync { rights_attenuation_masks, responder } =
6082 self
6083 {
6084 Some((rights_attenuation_masks, responder))
6085 } else {
6086 None
6087 }
6088 }
6089
6090 #[allow(irrefutable_let_patterns)]
6091 pub fn into_duplicate(
6092 self,
6093 ) -> Option<(
6094 u32,
6095 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
6096 BufferCollectionTokenControlHandle,
6097 )> {
6098 if let BufferCollectionTokenRequest::Duplicate {
6099 rights_attenuation_mask,
6100 token_request,
6101 control_handle,
6102 } = self
6103 {
6104 Some((rights_attenuation_mask, token_request, control_handle))
6105 } else {
6106 None
6107 }
6108 }
6109
6110 #[allow(irrefutable_let_patterns)]
6111 pub fn into_set_dispensable(self) -> Option<(BufferCollectionTokenControlHandle)> {
6112 if let BufferCollectionTokenRequest::SetDispensable { control_handle } = self {
6113 Some((control_handle))
6114 } else {
6115 None
6116 }
6117 }
6118
6119 #[allow(irrefutable_let_patterns)]
6120 pub fn into_create_buffer_collection_token_group(
6121 self,
6122 ) -> Option<(
6123 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
6124 BufferCollectionTokenControlHandle,
6125 )> {
6126 if let BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {
6127 group_request,
6128 control_handle,
6129 } = self
6130 {
6131 Some((group_request, control_handle))
6132 } else {
6133 None
6134 }
6135 }
6136
6137 /// Name of the method defined in FIDL
6138 pub fn method_name(&self) -> &'static str {
6139 match *self {
6140 BufferCollectionTokenRequest::Sync { .. } => "sync",
6141 BufferCollectionTokenRequest::Close { .. } => "close",
6142 BufferCollectionTokenRequest::SetName { .. } => "set_name",
6143 BufferCollectionTokenRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
6144 BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline { .. } => {
6145 "set_debug_timeout_log_deadline"
6146 }
6147 BufferCollectionTokenRequest::SetVerboseLogging { .. } => "set_verbose_logging",
6148 BufferCollectionTokenRequest::GetNodeRef { .. } => "get_node_ref",
6149 BufferCollectionTokenRequest::IsAlternateFor { .. } => "is_alternate_for",
6150 BufferCollectionTokenRequest::DuplicateSync { .. } => "duplicate_sync",
6151 BufferCollectionTokenRequest::Duplicate { .. } => "duplicate",
6152 BufferCollectionTokenRequest::SetDispensable { .. } => "set_dispensable",
6153 BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup { .. } => {
6154 "create_buffer_collection_token_group"
6155 }
6156 }
6157 }
6158}
6159
6160#[derive(Debug, Clone)]
6161pub struct BufferCollectionTokenControlHandle {
6162 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
6163}
6164
6165impl fidl::endpoints::ControlHandle for BufferCollectionTokenControlHandle {
6166 fn shutdown(&self) {
6167 self.inner.shutdown()
6168 }
6169
6170 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
6171 self.inner.shutdown_with_epitaph(status)
6172 }
6173
6174 fn is_closed(&self) -> bool {
6175 self.inner.channel().is_closed()
6176 }
6177 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
6178 self.inner.channel().on_closed()
6179 }
6180
6181 #[cfg(target_os = "fuchsia")]
6182 fn signal_peer(
6183 &self,
6184 clear_mask: zx::Signals,
6185 set_mask: zx::Signals,
6186 ) -> Result<(), zx_status::Status> {
6187 use fidl::Peered;
6188 self.inner.channel().signal_peer(clear_mask, set_mask)
6189 }
6190}
6191
6192impl BufferCollectionTokenControlHandle {}
6193
6194#[must_use = "FIDL methods require a response to be sent"]
6195#[derive(Debug)]
6196pub struct BufferCollectionTokenSyncResponder {
6197 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6198 tx_id: u32,
6199}
6200
6201/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6202/// if the responder is dropped without sending a response, so that the client
6203/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6204impl std::ops::Drop for BufferCollectionTokenSyncResponder {
6205 fn drop(&mut self) {
6206 self.control_handle.shutdown();
6207 // Safety: drops once, never accessed again
6208 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6209 }
6210}
6211
6212impl fidl::endpoints::Responder for BufferCollectionTokenSyncResponder {
6213 type ControlHandle = BufferCollectionTokenControlHandle;
6214
6215 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6216 &self.control_handle
6217 }
6218
6219 fn drop_without_shutdown(mut self) {
6220 // Safety: drops once, never accessed again due to mem::forget
6221 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6222 // Prevent Drop from running (which would shut down the channel)
6223 std::mem::forget(self);
6224 }
6225}
6226
6227impl BufferCollectionTokenSyncResponder {
6228 /// Sends a response to the FIDL transaction.
6229 ///
6230 /// Sets the channel to shutdown if an error occurs.
6231 pub fn send(self) -> Result<(), fidl::Error> {
6232 let _result = self.send_raw();
6233 if _result.is_err() {
6234 self.control_handle.shutdown();
6235 }
6236 self.drop_without_shutdown();
6237 _result
6238 }
6239
6240 /// Similar to "send" but does not shutdown the channel if an error occurs.
6241 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
6242 let _result = self.send_raw();
6243 self.drop_without_shutdown();
6244 _result
6245 }
6246
6247 fn send_raw(&self) -> Result<(), fidl::Error> {
6248 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
6249 (),
6250 self.tx_id,
6251 0x4577e238ae26291,
6252 fidl::encoding::DynamicFlags::empty(),
6253 )
6254 }
6255}
6256
6257#[must_use = "FIDL methods require a response to be sent"]
6258#[derive(Debug)]
6259pub struct BufferCollectionTokenGetNodeRefResponder {
6260 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6261 tx_id: u32,
6262}
6263
6264/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6265/// if the responder is dropped without sending a response, so that the client
6266/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6267impl std::ops::Drop for BufferCollectionTokenGetNodeRefResponder {
6268 fn drop(&mut self) {
6269 self.control_handle.shutdown();
6270 // Safety: drops once, never accessed again
6271 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6272 }
6273}
6274
6275impl fidl::endpoints::Responder for BufferCollectionTokenGetNodeRefResponder {
6276 type ControlHandle = BufferCollectionTokenControlHandle;
6277
6278 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6279 &self.control_handle
6280 }
6281
6282 fn drop_without_shutdown(mut self) {
6283 // Safety: drops once, never accessed again due to mem::forget
6284 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6285 // Prevent Drop from running (which would shut down the channel)
6286 std::mem::forget(self);
6287 }
6288}
6289
6290impl BufferCollectionTokenGetNodeRefResponder {
6291 /// Sends a response to the FIDL transaction.
6292 ///
6293 /// Sets the channel to shutdown if an error occurs.
6294 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6295 let _result = self.send_raw(node_ref);
6296 if _result.is_err() {
6297 self.control_handle.shutdown();
6298 }
6299 self.drop_without_shutdown();
6300 _result
6301 }
6302
6303 /// Similar to "send" but does not shutdown the channel if an error occurs.
6304 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6305 let _result = self.send_raw(node_ref);
6306 self.drop_without_shutdown();
6307 _result
6308 }
6309
6310 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6311 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
6312 (node_ref,),
6313 self.tx_id,
6314 0x467b7c75c35c3b84,
6315 fidl::encoding::DynamicFlags::empty(),
6316 )
6317 }
6318}
6319
6320#[must_use = "FIDL methods require a response to be sent"]
6321#[derive(Debug)]
6322pub struct BufferCollectionTokenIsAlternateForResponder {
6323 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6324 tx_id: u32,
6325}
6326
6327/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6328/// if the responder is dropped without sending a response, so that the client
6329/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6330impl std::ops::Drop for BufferCollectionTokenIsAlternateForResponder {
6331 fn drop(&mut self) {
6332 self.control_handle.shutdown();
6333 // Safety: drops once, never accessed again
6334 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6335 }
6336}
6337
6338impl fidl::endpoints::Responder for BufferCollectionTokenIsAlternateForResponder {
6339 type ControlHandle = BufferCollectionTokenControlHandle;
6340
6341 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6342 &self.control_handle
6343 }
6344
6345 fn drop_without_shutdown(mut self) {
6346 // Safety: drops once, never accessed again due to mem::forget
6347 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6348 // Prevent Drop from running (which would shut down the channel)
6349 std::mem::forget(self);
6350 }
6351}
6352
6353impl BufferCollectionTokenIsAlternateForResponder {
6354 /// Sends a response to the FIDL transaction.
6355 ///
6356 /// Sets the channel to shutdown if an error occurs.
6357 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6358 let _result = self.send_raw(result);
6359 if _result.is_err() {
6360 self.control_handle.shutdown();
6361 }
6362 self.drop_without_shutdown();
6363 _result
6364 }
6365
6366 /// Similar to "send" but does not shutdown the channel if an error occurs.
6367 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6368 let _result = self.send_raw(result);
6369 self.drop_without_shutdown();
6370 _result
6371 }
6372
6373 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6374 self.control_handle
6375 .inner
6376 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
6377 result.map(|is_alternate| (is_alternate,)),
6378 self.tx_id,
6379 0x33a2a7aff2776c07,
6380 fidl::encoding::DynamicFlags::empty(),
6381 )
6382 }
6383}
6384
6385#[must_use = "FIDL methods require a response to be sent"]
6386#[derive(Debug)]
6387pub struct BufferCollectionTokenDuplicateSyncResponder {
6388 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6389 tx_id: u32,
6390}
6391
6392/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6393/// if the responder is dropped without sending a response, so that the client
6394/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6395impl std::ops::Drop for BufferCollectionTokenDuplicateSyncResponder {
6396 fn drop(&mut self) {
6397 self.control_handle.shutdown();
6398 // Safety: drops once, never accessed again
6399 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6400 }
6401}
6402
6403impl fidl::endpoints::Responder for BufferCollectionTokenDuplicateSyncResponder {
6404 type ControlHandle = BufferCollectionTokenControlHandle;
6405
6406 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6407 &self.control_handle
6408 }
6409
6410 fn drop_without_shutdown(mut self) {
6411 // Safety: drops once, never accessed again due to mem::forget
6412 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6413 // Prevent Drop from running (which would shut down the channel)
6414 std::mem::forget(self);
6415 }
6416}
6417
6418impl BufferCollectionTokenDuplicateSyncResponder {
6419 /// Sends a response to the FIDL transaction.
6420 ///
6421 /// Sets the channel to shutdown if an error occurs.
6422 pub fn send(
6423 self,
6424 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6425 ) -> Result<(), fidl::Error> {
6426 let _result = self.send_raw(tokens);
6427 if _result.is_err() {
6428 self.control_handle.shutdown();
6429 }
6430 self.drop_without_shutdown();
6431 _result
6432 }
6433
6434 /// Similar to "send" but does not shutdown the channel if an error occurs.
6435 pub fn send_no_shutdown_on_err(
6436 self,
6437 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6438 ) -> Result<(), fidl::Error> {
6439 let _result = self.send_raw(tokens);
6440 self.drop_without_shutdown();
6441 _result
6442 }
6443
6444 fn send_raw(
6445 &self,
6446 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6447 ) -> Result<(), fidl::Error> {
6448 self.control_handle.inner.send::<BufferCollectionTokenDuplicateSyncResponse>(
6449 (tokens.as_mut(),),
6450 self.tx_id,
6451 0x49ed7ab7cc19f18,
6452 fidl::encoding::DynamicFlags::empty(),
6453 )
6454 }
6455}
6456
6457#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
6458pub struct BufferCollectionTokenGroupMarker;
6459
6460impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenGroupMarker {
6461 type Proxy = BufferCollectionTokenGroupProxy;
6462 type RequestStream = BufferCollectionTokenGroupRequestStream;
6463 #[cfg(target_os = "fuchsia")]
6464 type SynchronousProxy = BufferCollectionTokenGroupSynchronousProxy;
6465
6466 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionTokenGroup";
6467}
6468
6469pub trait BufferCollectionTokenGroupProxyInterface: Send + Sync {
6470 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
6471 fn r#sync(&self) -> Self::SyncResponseFut;
6472 fn r#close(&self) -> Result<(), fidl::Error>;
6473 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
6474 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
6475 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
6476 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
6477 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
6478 + Send;
6479 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
6480 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
6481 + Send;
6482 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
6483 fn r#create_child(
6484 &self,
6485 payload: BufferCollectionTokenGroupCreateChildRequest,
6486 ) -> Result<(), fidl::Error>;
6487 type CreateChildrenSyncResponseFut: std::future::Future<
6488 Output = Result<
6489 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6490 fidl::Error,
6491 >,
6492 > + Send;
6493 fn r#create_children_sync(
6494 &self,
6495 rights_attenuation_masks: &[fidl::Rights],
6496 ) -> Self::CreateChildrenSyncResponseFut;
6497 fn r#all_children_present(&self) -> Result<(), fidl::Error>;
6498}
6499#[derive(Debug)]
6500#[cfg(target_os = "fuchsia")]
6501pub struct BufferCollectionTokenGroupSynchronousProxy {
6502 client: fidl::client::sync::Client,
6503}
6504
6505#[cfg(target_os = "fuchsia")]
6506impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenGroupSynchronousProxy {
6507 type Proxy = BufferCollectionTokenGroupProxy;
6508 type Protocol = BufferCollectionTokenGroupMarker;
6509
6510 fn from_channel(inner: fidl::Channel) -> Self {
6511 Self::new(inner)
6512 }
6513
6514 fn into_channel(self) -> fidl::Channel {
6515 self.client.into_channel()
6516 }
6517
6518 fn as_channel(&self) -> &fidl::Channel {
6519 self.client.as_channel()
6520 }
6521}
6522
6523#[cfg(target_os = "fuchsia")]
6524impl BufferCollectionTokenGroupSynchronousProxy {
6525 pub fn new(channel: fidl::Channel) -> Self {
6526 let protocol_name =
6527 <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
6528 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
6529 }
6530
6531 pub fn into_channel(self) -> fidl::Channel {
6532 self.client.into_channel()
6533 }
6534
6535 /// Waits until an event arrives and returns it. It is safe for other
6536 /// threads to make concurrent requests while waiting for an event.
6537 pub fn wait_for_event(
6538 &self,
6539 deadline: zx::MonotonicInstant,
6540 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
6541 BufferCollectionTokenGroupEvent::decode(self.client.wait_for_event(deadline)?)
6542 }
6543
6544 /// Ensure that previous messages, including Duplicate() messages on a
6545 /// token, collection, or group, have been received server side.
6546 ///
6547 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
6548 /// valid sysmem token risks the Sync() hanging forever. See
6549 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
6550 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
6551 /// Another way is to pass the token to BindSharedCollection(), which also
6552 /// validates the token as part of exchanging it for a BufferCollection
6553 /// channel, and BufferCollection Sync() can then be used.
6554 ///
6555 /// After a Sync(), it's then safe to send the client end of token_request
6556 /// to another participant knowing the server will recognize the token when
6557 /// it's sent into BindSharedCollection() by the other participant.
6558 ///
6559 /// Other options include waiting for each token.Duplicate() to complete
6560 /// individually (using separate call to token.Sync() after each), or
6561 /// calling Sync() on BufferCollection after the token has been turned in
6562 /// via BindSharedCollection().
6563 ///
6564 /// Another way to mitigate is to avoid calling Sync() on the token, and
6565 /// instead later deal with potential failure of BufferCollection.Sync() if
6566 /// the original token was invalid. This option can be preferable from a
6567 /// performance point of view, but requires client code to delay sending
6568 /// tokens duplicated from this token until after client code has converted
6569 /// the duplicating token to a BufferCollection and received successful
6570 /// response from BufferCollection.Sync().
6571 ///
6572 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
6573 /// When BufferCollection.Sync() isn't feasible, the caller must already
6574 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
6575 /// hang forever. See ValidateBufferCollectionToken() to check token
6576 /// validity first if the token isn't already known to be (is/was) valid.
6577 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
6578 let _response =
6579 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
6580 (),
6581 0x4577e238ae26291,
6582 fidl::encoding::DynamicFlags::empty(),
6583 ___deadline,
6584 )?;
6585 Ok(_response)
6586 }
6587
6588 /// On a BufferCollectionToken channel:
6589 ///
6590 /// Normally a participant will convert a BufferCollectionToken into a
6591 /// BufferCollection view, but a participant is also free to Close() the
6592 /// token (and then close the channel immediately or shortly later in
6593 /// response to server closing its end), which avoids causing logical buffer
6594 /// collection failure. Â Normally an unexpected token channel close will
6595 /// cause logical buffer collection failure (the only exceptions being
6596 /// certain cases involving AttachToken() or SetDispensable()).
6597 ///
6598 /// On a BufferCollection channel:
6599 ///
6600 /// By default the server handles unexpected failure of a BufferCollection
6601 /// by failing the whole logical buffer collection. Partly this is to
6602 /// expedite closing VMO handles to reclaim memory when any participant
6603 /// fails. If a participant would like to cleanly close a BufferCollection
6604 /// view without causing logical buffer collection failure, the participant
6605 /// can send Close() before closing the client end of the BufferCollection
6606 /// channel. If this is the last BufferCollection view, the logical buffer
6607 /// collection will still go away. The Close() can occur before or after
6608 /// SetConstraints(). If before SetConstraints(), the buffer collection
6609 /// won't require constraints from this node in order to allocate. If
6610 /// after SetConstraints(), the constraints are retained and aggregated
6611 /// along with any subsequent logical allocation(s), despite the lack of
6612 /// channel connection.
6613 ///
6614 /// On a BufferCollectionTokenGroup channel:
6615 ///
6616 /// By default, unexpected failure of a BufferCollectionTokenGroup will
6617 /// trigger failure of the logical BufferCollectionTokenGroup and will
6618 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
6619 /// channel without failing the logical group or propagating failure, send
6620 /// Close() before closing the channel client endpoint.
6621 ///
6622 /// If Close() occurs before AllChildrenPresent(), the logical buffer
6623 /// collection will still fail despite the Close() (because sysmem can't be
6624 /// sure whether all relevant children were created, so it's ambiguous
6625 /// whether all relevant constraints will be provided to sysmem). If
6626 /// Close() occurs after AllChildrenPresent(), the children and all their
6627 /// constraints remain intact (just as they would if the
6628 /// BufferCollectionTokenGroup channel had remained open), and the close
6629 /// doesn't trigger or propagate failure.
6630 pub fn r#close(&self) -> Result<(), fidl::Error> {
6631 self.client.send::<fidl::encoding::EmptyPayload>(
6632 (),
6633 0x5b1d7a4f5681fca7,
6634 fidl::encoding::DynamicFlags::empty(),
6635 )
6636 }
6637
6638 /// Set a name for VMOs in this buffer collection. The name may be truncated
6639 /// shorter. The name only affects VMOs allocated after it's set - this call
6640 /// does not rename existing VMOs. If multiple clients set different names
6641 /// then the larger priority value will win.
6642 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
6643 self.client.send::<NodeSetNameRequest>(
6644 (priority, name),
6645 0x77a41bb6217e2443,
6646 fidl::encoding::DynamicFlags::empty(),
6647 )
6648 }
6649
6650 /// Set information about the current client that can be used by sysmem to
6651 /// help debug leaking memory and hangs waiting for constraints. |name| can
6652 /// be an arbitrary string, but the current process name (see
6653 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
6654 /// arbitrary id, but the current process ID (see
6655 /// fsl::GetCurrentProcessKoid()) is a good default.
6656 ///
6657 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
6658 /// indicate which client is closing their channel first, leading to
6659 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
6660 /// over, but if happening earlier than expected, the
6661 /// client-channel-specific name can help diagnose where the failure is
6662 /// first coming from, from sysmem's point of view).
6663 ///
6664 /// By default (unless overriden by this message or using
6665 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
6666 /// parent Node at the time the child Node is created. While this can be
6667 /// better than nothing, it's often better for each participant to use
6668 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
6669 /// info directly relevant to the current client. Also, SetVerboseLogging()
6670 /// can be used to help disambiguate if a Node is suspected of having info
6671 /// that was copied from its parent.
6672 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
6673 self.client.send::<NodeSetDebugClientInfoRequest>(
6674 (name, id),
6675 0x7275759070eb5ee2,
6676 fidl::encoding::DynamicFlags::empty(),
6677 )
6678 }
6679
6680 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
6681 /// after creating a collection. Clients can call this method to change
6682 /// when the log is printed. If multiple client set the deadline, it's
6683 /// unspecified which deadline will take effect.
6684 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
6685 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
6686 (deadline,),
6687 0x46d38f4772638867,
6688 fidl::encoding::DynamicFlags::empty(),
6689 )
6690 }
6691
6692 /// Verbose logging includes constraints set via SetConstraints() from each
6693 /// client along with info set via SetDebugClientInfo() and the structure of
6694 /// the tree of Node(s).
6695 ///
6696 /// Normally sysmem prints only a single line complaint when aggregation
6697 /// fails, with just the specific detailed reason that aggregation failed,
6698 /// with minimal context. While this is often enough to diagnose a problem
6699 /// if only a small change was made and the system had been working before
6700 /// the small change, it's often not particularly helpful for getting a new
6701 /// buffer collection to work for the first time. Especially with more
6702 /// complex trees of nodes, involving things like AttachToken(),
6703 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
6704 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
6705 /// looks like and why it's failing a logical allocation, or why a tree or
6706 /// sub-tree is failing sooner than expected.
6707 ///
6708 /// The intent of the extra logging is to be acceptable from a performance
6709 /// point of view, if only enabled on a low number of buffer collections.
6710 /// If we're not tracking down a bug, we shouldn't send this message.
6711 ///
6712 /// If too many participants leave verbose logging enabled, we may end up
6713 /// needing to require that system-wide sysmem verbose logging be permitted
6714 /// via some other setting, to avoid sysmem spamming the log too much due to
6715 /// this message.
6716 ///
6717 /// This may be a NOP for some nodes due to intentional policy associated
6718 /// with the node, if we don't trust a node enough to let it turn on verbose
6719 /// logging.
6720 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
6721 self.client.send::<fidl::encoding::EmptyPayload>(
6722 (),
6723 0x6bfbe2cf1701d288,
6724 fidl::encoding::DynamicFlags::empty(),
6725 )
6726 }
6727
6728 /// This gets an event handle that can be used as a parameter to
6729 /// IsAlternateFor() called on any Node. The client will not be granted the
6730 /// right to signal this event, as this handle should only be used as proof
6731 /// that the client obtained this handle from this Node.
6732 ///
6733 /// Because this is a get not a set, no Sync() is needed between the
6734 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
6735 /// potentially being on different channels.
6736 ///
6737 /// See also IsAlternateFor().
6738 pub fn r#get_node_ref(
6739 &self,
6740 ___deadline: zx::MonotonicInstant,
6741 ) -> Result<fidl::Event, fidl::Error> {
6742 let _response =
6743 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
6744 (),
6745 0x467b7c75c35c3b84,
6746 fidl::encoding::DynamicFlags::empty(),
6747 ___deadline,
6748 )?;
6749 Ok(_response.node_ref)
6750 }
6751
6752 /// This checks whether the calling node is in a subtree rooted at a
6753 /// different child token of a common parent BufferCollectionTokenGroup, in
6754 /// relation to the passed-in node_ref.
6755 ///
6756 /// This call is for assisting with admission control de-duplication, and
6757 /// with debugging.
6758 ///
6759 /// The node_ref must be obtained using GetNodeRef() of a
6760 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
6761 ///
6762 /// The node_ref can be a duplicated handle; it's not necessary to call
6763 /// GetNodeRef() for every call to IsAlternateFor().
6764 ///
6765 /// If a calling token may not actually be a valid token at all due to
6766 /// a potentially hostile/untrusted provider of the token, call
6767 /// ValidateBufferCollectionToken() first instead of potentially getting
6768 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
6769 /// token not being a real token (not really talking to sysmem). Another
6770 /// option is to call BindSharedCollection with this token first which also
6771 /// validates the token along with converting it to a BufferCollection, then
6772 /// call BufferCollection IsAlternateFor().
6773 ///
6774 /// error values:
6775 ///
6776 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
6777 /// buffer collection as the calling Node. Before logical allocation and
6778 /// within the same logical allocation sub-tree, this essentially means that
6779 /// the node_ref was never part of this logical buffer collection, since
6780 /// before logical allocation all node_refs that come into existence remain
6781 /// in existence at least until logical allocation (including Node(s) that
6782 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
6783 /// to be returned, this Node's channel needs to still be connected server
6784 /// side, which won't be the case if the whole logical allocation has
6785 /// failed. After logical allocation or in a different logical allocation
6786 /// sub-tree there are additional potential reasons for this error. For
6787 /// example a different logical allocation (separated from this Node(s)
6788 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
6789 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
6790 /// exist and may select a different child sub-tree than the sub-tree the
6791 /// node_ref is in causing deletion of the node_ref Node. The only time
6792 /// sysmem keeps a Node around after that Node has no corresponding channel
6793 /// is when Close() is used and the Node's sub-tree has not yet failed.
6794 /// Another reason for this error is if the node_ref is an eventpair handle
6795 /// with sufficient rights, but isn't actually a real node_ref obtained from
6796 /// GetNodeRef().
6797 ///
6798 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
6799 /// eventpair handle, or doesn't have the needed rights expected on a real
6800 /// node_ref.
6801 ///
6802 /// No other failing status codes are returned by this call. However,
6803 /// sysmem may add additional codes in future, so the client should have
6804 /// sensible default handling for any failing status code.
6805 ///
6806 /// On success, is_alternate has the following meaning:
6807 /// * true - The first parent node in common between the calling node and
6808 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
6809 /// the calling Node and the node_ref Node will _not_ have both their
6810 /// constraints apply - rather sysmem will choose one or the other of
6811 /// the constraints - never both. This is because only one child of
6812 /// a BufferCollectionTokenGroup is selected during logical allocation,
6813 /// with only that one child's sub-tree contributing to constraints
6814 /// aggregation.
6815 /// * false - The first parent node in common between the calling Node and
6816 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
6817 /// this means the first parent node in common is a
6818 /// BufferCollectionToken or BufferCollection (regardless of not
6819 /// Close()ed or Close()ed). This means that the calling Node and the
6820 /// node_ref Node _may_ have both their constraints apply during
6821 /// constraints aggregation of the logical allocation, if both Node(s)
6822 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
6823 /// In this case, there is no BufferCollectionTokenGroup that will
6824 /// directly prevent the two Node(s) from both being selected and their
6825 /// constraints both aggregated, but even when false, one or both
6826 /// Node(s) may still be eliminated from consideration if one or both
6827 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
6828 /// which selects a child sub-tree other than the sub-tree containing
6829 /// the calling Node or node_ref Node.
6830 pub fn r#is_alternate_for(
6831 &self,
6832 mut node_ref: fidl::Event,
6833 ___deadline: zx::MonotonicInstant,
6834 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
6835 let _response = self.client.send_query::<
6836 NodeIsAlternateForRequest,
6837 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
6838 >(
6839 (node_ref,),
6840 0x33a2a7aff2776c07,
6841 fidl::encoding::DynamicFlags::empty(),
6842 ___deadline,
6843 )?;
6844 Ok(_response.map(|x| x.is_alternate))
6845 }
6846
6847 /// Create a child token. Before passing the client end of this token to
6848 /// BindSharedCollection(), completion of Sync() after CreateChild() is
6849 /// required. Or the client can use CreateChildrenSync() which essentially
6850 /// includes the Sync().
6851 ///
6852 /// token_request - the server end of the new token channel.
6853 ///
6854 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
6855 /// allows the holder to get the same rights to buffers as the parent token
6856 /// (of the group) had.
6857 pub fn r#create_child(
6858 &self,
6859 mut payload: BufferCollectionTokenGroupCreateChildRequest,
6860 ) -> Result<(), fidl::Error> {
6861 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
6862 &mut payload,
6863 0x2e74f8bcbf59ee59,
6864 fidl::encoding::DynamicFlags::empty(),
6865 )
6866 }
6867
6868 /// Create 1 or more child tokens at once, synchronously. In contrast to
6869 /// CreateChild(), no Sync() completion is required before passing the
6870 /// client end of a returned token to BindSharedCollection().
6871 ///
6872 /// The size of the rights_attentuation_mask determines the number of
6873 /// created child tokens.
6874 ///
6875 /// The lower-index child tokens are higher priority (attempted sooner) than
6876 /// higher-index child tokens.
6877 ///
6878 /// As per all child tokens, successful aggregation will choose exactly one
6879 /// child among all created children (across all children created across
6880 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
6881 ///
6882 /// The maximum permissible total number of children per group, and total
6883 /// number of nodes in an overall tree (from the root) are capped to limits
6884 /// which are not configurable via these protocols.
6885 pub fn r#create_children_sync(
6886 &self,
6887 mut rights_attenuation_masks: &[fidl::Rights],
6888 ___deadline: zx::MonotonicInstant,
6889 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error> {
6890 let _response = self.client.send_query::<
6891 BufferCollectionTokenGroupCreateChildrenSyncRequest,
6892 BufferCollectionTokenGroupCreateChildrenSyncResponse,
6893 >(
6894 (rights_attenuation_masks,),
6895 0x569dc3ca2a98f535,
6896 fidl::encoding::DynamicFlags::empty(),
6897 ___deadline,
6898 )?;
6899 Ok(_response.tokens)
6900 }
6901
6902 /// AllChildrenPresent()
6903 ///
6904 /// After creating all children, the client must call AllChildrenPresent()
6905 /// to inform sysmem that no more children will be created, so that sysmem
6906 /// can know when it's ok to start aggregating constraints.
6907 ///
6908 /// If Close() is to be sent, it should be sent _after_
6909 /// AllChildrenPresent(), else failure of the group and propagation of the
6910 /// failure to the group's parent will still be triggered.
6911 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
6912 self.client.send::<fidl::encoding::EmptyPayload>(
6913 (),
6914 0x1d41715f6f044b50,
6915 fidl::encoding::DynamicFlags::empty(),
6916 )
6917 }
6918}
6919
6920#[cfg(target_os = "fuchsia")]
6921impl From<BufferCollectionTokenGroupSynchronousProxy> for zx::NullableHandle {
6922 fn from(value: BufferCollectionTokenGroupSynchronousProxy) -> Self {
6923 value.into_channel().into()
6924 }
6925}
6926
6927#[cfg(target_os = "fuchsia")]
6928impl From<fidl::Channel> for BufferCollectionTokenGroupSynchronousProxy {
6929 fn from(value: fidl::Channel) -> Self {
6930 Self::new(value)
6931 }
6932}
6933
6934#[cfg(target_os = "fuchsia")]
6935impl fidl::endpoints::FromClient for BufferCollectionTokenGroupSynchronousProxy {
6936 type Protocol = BufferCollectionTokenGroupMarker;
6937
6938 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionTokenGroupMarker>) -> Self {
6939 Self::new(value.into_channel())
6940 }
6941}
6942
6943#[derive(Debug, Clone)]
6944pub struct BufferCollectionTokenGroupProxy {
6945 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
6946}
6947
6948impl fidl::endpoints::Proxy for BufferCollectionTokenGroupProxy {
6949 type Protocol = BufferCollectionTokenGroupMarker;
6950
6951 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
6952 Self::new(inner)
6953 }
6954
6955 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
6956 self.client.into_channel().map_err(|client| Self { client })
6957 }
6958
6959 fn as_channel(&self) -> &::fidl::AsyncChannel {
6960 self.client.as_channel()
6961 }
6962}
6963
6964impl BufferCollectionTokenGroupProxy {
6965 /// Create a new Proxy for fuchsia.sysmem/BufferCollectionTokenGroup.
6966 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
6967 let protocol_name =
6968 <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
6969 Self { client: fidl::client::Client::new(channel, protocol_name) }
6970 }
6971
6972 /// Get a Stream of events from the remote end of the protocol.
6973 ///
6974 /// # Panics
6975 ///
6976 /// Panics if the event stream was already taken.
6977 pub fn take_event_stream(&self) -> BufferCollectionTokenGroupEventStream {
6978 BufferCollectionTokenGroupEventStream { event_receiver: self.client.take_event_receiver() }
6979 }
6980
6981 /// Ensure that previous messages, including Duplicate() messages on a
6982 /// token, collection, or group, have been received server side.
6983 ///
6984 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
6985 /// valid sysmem token risks the Sync() hanging forever. See
6986 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
6987 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
6988 /// Another way is to pass the token to BindSharedCollection(), which also
6989 /// validates the token as part of exchanging it for a BufferCollection
6990 /// channel, and BufferCollection Sync() can then be used.
6991 ///
6992 /// After a Sync(), it's then safe to send the client end of token_request
6993 /// to another participant knowing the server will recognize the token when
6994 /// it's sent into BindSharedCollection() by the other participant.
6995 ///
6996 /// Other options include waiting for each token.Duplicate() to complete
6997 /// individually (using separate call to token.Sync() after each), or
6998 /// calling Sync() on BufferCollection after the token has been turned in
6999 /// via BindSharedCollection().
7000 ///
7001 /// Another way to mitigate is to avoid calling Sync() on the token, and
7002 /// instead later deal with potential failure of BufferCollection.Sync() if
7003 /// the original token was invalid. This option can be preferable from a
7004 /// performance point of view, but requires client code to delay sending
7005 /// tokens duplicated from this token until after client code has converted
7006 /// the duplicating token to a BufferCollection and received successful
7007 /// response from BufferCollection.Sync().
7008 ///
7009 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
7010 /// When BufferCollection.Sync() isn't feasible, the caller must already
7011 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
7012 /// hang forever. See ValidateBufferCollectionToken() to check token
7013 /// validity first if the token isn't already known to be (is/was) valid.
7014 pub fn r#sync(
7015 &self,
7016 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
7017 BufferCollectionTokenGroupProxyInterface::r#sync(self)
7018 }
7019
7020 /// On a BufferCollectionToken channel:
7021 ///
7022 /// Normally a participant will convert a BufferCollectionToken into a
7023 /// BufferCollection view, but a participant is also free to Close() the
7024 /// token (and then close the channel immediately or shortly later in
7025 /// response to server closing its end), which avoids causing logical buffer
7026 /// collection failure. Â Normally an unexpected token channel close will
7027 /// cause logical buffer collection failure (the only exceptions being
7028 /// certain cases involving AttachToken() or SetDispensable()).
7029 ///
7030 /// On a BufferCollection channel:
7031 ///
7032 /// By default the server handles unexpected failure of a BufferCollection
7033 /// by failing the whole logical buffer collection. Partly this is to
7034 /// expedite closing VMO handles to reclaim memory when any participant
7035 /// fails. If a participant would like to cleanly close a BufferCollection
7036 /// view without causing logical buffer collection failure, the participant
7037 /// can send Close() before closing the client end of the BufferCollection
7038 /// channel. If this is the last BufferCollection view, the logical buffer
7039 /// collection will still go away. The Close() can occur before or after
7040 /// SetConstraints(). If before SetConstraints(), the buffer collection
7041 /// won't require constraints from this node in order to allocate. If
7042 /// after SetConstraints(), the constraints are retained and aggregated
7043 /// along with any subsequent logical allocation(s), despite the lack of
7044 /// channel connection.
7045 ///
7046 /// On a BufferCollectionTokenGroup channel:
7047 ///
7048 /// By default, unexpected failure of a BufferCollectionTokenGroup will
7049 /// trigger failure of the logical BufferCollectionTokenGroup and will
7050 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
7051 /// channel without failing the logical group or propagating failure, send
7052 /// Close() before closing the channel client endpoint.
7053 ///
7054 /// If Close() occurs before AllChildrenPresent(), the logical buffer
7055 /// collection will still fail despite the Close() (because sysmem can't be
7056 /// sure whether all relevant children were created, so it's ambiguous
7057 /// whether all relevant constraints will be provided to sysmem). If
7058 /// Close() occurs after AllChildrenPresent(), the children and all their
7059 /// constraints remain intact (just as they would if the
7060 /// BufferCollectionTokenGroup channel had remained open), and the close
7061 /// doesn't trigger or propagate failure.
7062 pub fn r#close(&self) -> Result<(), fidl::Error> {
7063 BufferCollectionTokenGroupProxyInterface::r#close(self)
7064 }
7065
7066 /// Set a name for VMOs in this buffer collection. The name may be truncated
7067 /// shorter. The name only affects VMOs allocated after it's set - this call
7068 /// does not rename existing VMOs. If multiple clients set different names
7069 /// then the larger priority value will win.
7070 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
7071 BufferCollectionTokenGroupProxyInterface::r#set_name(self, priority, name)
7072 }
7073
7074 /// Set information about the current client that can be used by sysmem to
7075 /// help debug leaking memory and hangs waiting for constraints. |name| can
7076 /// be an arbitrary string, but the current process name (see
7077 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
7078 /// arbitrary id, but the current process ID (see
7079 /// fsl::GetCurrentProcessKoid()) is a good default.
7080 ///
7081 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
7082 /// indicate which client is closing their channel first, leading to
7083 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
7084 /// over, but if happening earlier than expected, the
7085 /// client-channel-specific name can help diagnose where the failure is
7086 /// first coming from, from sysmem's point of view).
7087 ///
7088 /// By default (unless overriden by this message or using
7089 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
7090 /// parent Node at the time the child Node is created. While this can be
7091 /// better than nothing, it's often better for each participant to use
7092 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
7093 /// info directly relevant to the current client. Also, SetVerboseLogging()
7094 /// can be used to help disambiguate if a Node is suspected of having info
7095 /// that was copied from its parent.
7096 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
7097 BufferCollectionTokenGroupProxyInterface::r#set_debug_client_info(self, name, id)
7098 }
7099
7100 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
7101 /// after creating a collection. Clients can call this method to change
7102 /// when the log is printed. If multiple client set the deadline, it's
7103 /// unspecified which deadline will take effect.
7104 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
7105 BufferCollectionTokenGroupProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
7106 }
7107
7108 /// Verbose logging includes constraints set via SetConstraints() from each
7109 /// client along with info set via SetDebugClientInfo() and the structure of
7110 /// the tree of Node(s).
7111 ///
7112 /// Normally sysmem prints only a single line complaint when aggregation
7113 /// fails, with just the specific detailed reason that aggregation failed,
7114 /// with minimal context. While this is often enough to diagnose a problem
7115 /// if only a small change was made and the system had been working before
7116 /// the small change, it's often not particularly helpful for getting a new
7117 /// buffer collection to work for the first time. Especially with more
7118 /// complex trees of nodes, involving things like AttachToken(),
7119 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
7120 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
7121 /// looks like and why it's failing a logical allocation, or why a tree or
7122 /// sub-tree is failing sooner than expected.
7123 ///
7124 /// The intent of the extra logging is to be acceptable from a performance
7125 /// point of view, if only enabled on a low number of buffer collections.
7126 /// If we're not tracking down a bug, we shouldn't send this message.
7127 ///
7128 /// If too many participants leave verbose logging enabled, we may end up
7129 /// needing to require that system-wide sysmem verbose logging be permitted
7130 /// via some other setting, to avoid sysmem spamming the log too much due to
7131 /// this message.
7132 ///
7133 /// This may be a NOP for some nodes due to intentional policy associated
7134 /// with the node, if we don't trust a node enough to let it turn on verbose
7135 /// logging.
7136 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7137 BufferCollectionTokenGroupProxyInterface::r#set_verbose_logging(self)
7138 }
7139
7140 /// This gets an event handle that can be used as a parameter to
7141 /// IsAlternateFor() called on any Node. The client will not be granted the
7142 /// right to signal this event, as this handle should only be used as proof
7143 /// that the client obtained this handle from this Node.
7144 ///
7145 /// Because this is a get not a set, no Sync() is needed between the
7146 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
7147 /// potentially being on different channels.
7148 ///
7149 /// See also IsAlternateFor().
7150 pub fn r#get_node_ref(
7151 &self,
7152 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
7153 {
7154 BufferCollectionTokenGroupProxyInterface::r#get_node_ref(self)
7155 }
7156
7157 /// This checks whether the calling node is in a subtree rooted at a
7158 /// different child token of a common parent BufferCollectionTokenGroup, in
7159 /// relation to the passed-in node_ref.
7160 ///
7161 /// This call is for assisting with admission control de-duplication, and
7162 /// with debugging.
7163 ///
7164 /// The node_ref must be obtained using GetNodeRef() of a
7165 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
7166 ///
7167 /// The node_ref can be a duplicated handle; it's not necessary to call
7168 /// GetNodeRef() for every call to IsAlternateFor().
7169 ///
7170 /// If a calling token may not actually be a valid token at all due to
7171 /// a potentially hostile/untrusted provider of the token, call
7172 /// ValidateBufferCollectionToken() first instead of potentially getting
7173 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
7174 /// token not being a real token (not really talking to sysmem). Another
7175 /// option is to call BindSharedCollection with this token first which also
7176 /// validates the token along with converting it to a BufferCollection, then
7177 /// call BufferCollection IsAlternateFor().
7178 ///
7179 /// error values:
7180 ///
7181 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
7182 /// buffer collection as the calling Node. Before logical allocation and
7183 /// within the same logical allocation sub-tree, this essentially means that
7184 /// the node_ref was never part of this logical buffer collection, since
7185 /// before logical allocation all node_refs that come into existence remain
7186 /// in existence at least until logical allocation (including Node(s) that
7187 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
7188 /// to be returned, this Node's channel needs to still be connected server
7189 /// side, which won't be the case if the whole logical allocation has
7190 /// failed. After logical allocation or in a different logical allocation
7191 /// sub-tree there are additional potential reasons for this error. For
7192 /// example a different logical allocation (separated from this Node(s)
7193 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
7194 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
7195 /// exist and may select a different child sub-tree than the sub-tree the
7196 /// node_ref is in causing deletion of the node_ref Node. The only time
7197 /// sysmem keeps a Node around after that Node has no corresponding channel
7198 /// is when Close() is used and the Node's sub-tree has not yet failed.
7199 /// Another reason for this error is if the node_ref is an eventpair handle
7200 /// with sufficient rights, but isn't actually a real node_ref obtained from
7201 /// GetNodeRef().
7202 ///
7203 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
7204 /// eventpair handle, or doesn't have the needed rights expected on a real
7205 /// node_ref.
7206 ///
7207 /// No other failing status codes are returned by this call. However,
7208 /// sysmem may add additional codes in future, so the client should have
7209 /// sensible default handling for any failing status code.
7210 ///
7211 /// On success, is_alternate has the following meaning:
7212 /// * true - The first parent node in common between the calling node and
7213 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
7214 /// the calling Node and the node_ref Node will _not_ have both their
7215 /// constraints apply - rather sysmem will choose one or the other of
7216 /// the constraints - never both. This is because only one child of
7217 /// a BufferCollectionTokenGroup is selected during logical allocation,
7218 /// with only that one child's sub-tree contributing to constraints
7219 /// aggregation.
7220 /// * false - The first parent node in common between the calling Node and
7221 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
7222 /// this means the first parent node in common is a
7223 /// BufferCollectionToken or BufferCollection (regardless of not
7224 /// Close()ed or Close()ed). This means that the calling Node and the
7225 /// node_ref Node _may_ have both their constraints apply during
7226 /// constraints aggregation of the logical allocation, if both Node(s)
7227 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
7228 /// In this case, there is no BufferCollectionTokenGroup that will
7229 /// directly prevent the two Node(s) from both being selected and their
7230 /// constraints both aggregated, but even when false, one or both
7231 /// Node(s) may still be eliminated from consideration if one or both
7232 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
7233 /// which selects a child sub-tree other than the sub-tree containing
7234 /// the calling Node or node_ref Node.
7235 pub fn r#is_alternate_for(
7236 &self,
7237 mut node_ref: fidl::Event,
7238 ) -> fidl::client::QueryResponseFut<
7239 NodeIsAlternateForResult,
7240 fidl::encoding::DefaultFuchsiaResourceDialect,
7241 > {
7242 BufferCollectionTokenGroupProxyInterface::r#is_alternate_for(self, node_ref)
7243 }
7244
7245 /// Create a child token. Before passing the client end of this token to
7246 /// BindSharedCollection(), completion of Sync() after CreateChild() is
7247 /// required. Or the client can use CreateChildrenSync() which essentially
7248 /// includes the Sync().
7249 ///
7250 /// token_request - the server end of the new token channel.
7251 ///
7252 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
7253 /// allows the holder to get the same rights to buffers as the parent token
7254 /// (of the group) had.
7255 pub fn r#create_child(
7256 &self,
7257 mut payload: BufferCollectionTokenGroupCreateChildRequest,
7258 ) -> Result<(), fidl::Error> {
7259 BufferCollectionTokenGroupProxyInterface::r#create_child(self, payload)
7260 }
7261
7262 /// Create 1 or more child tokens at once, synchronously. In contrast to
7263 /// CreateChild(), no Sync() completion is required before passing the
7264 /// client end of a returned token to BindSharedCollection().
7265 ///
7266 /// The size of the rights_attentuation_mask determines the number of
7267 /// created child tokens.
7268 ///
7269 /// The lower-index child tokens are higher priority (attempted sooner) than
7270 /// higher-index child tokens.
7271 ///
7272 /// As per all child tokens, successful aggregation will choose exactly one
7273 /// child among all created children (across all children created across
7274 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
7275 ///
7276 /// The maximum permissible total number of children per group, and total
7277 /// number of nodes in an overall tree (from the root) are capped to limits
7278 /// which are not configurable via these protocols.
7279 pub fn r#create_children_sync(
7280 &self,
7281 mut rights_attenuation_masks: &[fidl::Rights],
7282 ) -> fidl::client::QueryResponseFut<
7283 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7284 fidl::encoding::DefaultFuchsiaResourceDialect,
7285 > {
7286 BufferCollectionTokenGroupProxyInterface::r#create_children_sync(
7287 self,
7288 rights_attenuation_masks,
7289 )
7290 }
7291
7292 /// AllChildrenPresent()
7293 ///
7294 /// After creating all children, the client must call AllChildrenPresent()
7295 /// to inform sysmem that no more children will be created, so that sysmem
7296 /// can know when it's ok to start aggregating constraints.
7297 ///
7298 /// If Close() is to be sent, it should be sent _after_
7299 /// AllChildrenPresent(), else failure of the group and propagation of the
7300 /// failure to the group's parent will still be triggered.
7301 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
7302 BufferCollectionTokenGroupProxyInterface::r#all_children_present(self)
7303 }
7304}
7305
7306impl BufferCollectionTokenGroupProxyInterface for BufferCollectionTokenGroupProxy {
7307 type SyncResponseFut =
7308 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
7309 fn r#sync(&self) -> Self::SyncResponseFut {
7310 fn _decode(
7311 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7312 ) -> Result<(), fidl::Error> {
7313 let _response = fidl::client::decode_transaction_body::<
7314 fidl::encoding::EmptyPayload,
7315 fidl::encoding::DefaultFuchsiaResourceDialect,
7316 0x4577e238ae26291,
7317 >(_buf?)?;
7318 Ok(_response)
7319 }
7320 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
7321 (),
7322 0x4577e238ae26291,
7323 fidl::encoding::DynamicFlags::empty(),
7324 _decode,
7325 )
7326 }
7327
7328 fn r#close(&self) -> Result<(), fidl::Error> {
7329 self.client.send::<fidl::encoding::EmptyPayload>(
7330 (),
7331 0x5b1d7a4f5681fca7,
7332 fidl::encoding::DynamicFlags::empty(),
7333 )
7334 }
7335
7336 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
7337 self.client.send::<NodeSetNameRequest>(
7338 (priority, name),
7339 0x77a41bb6217e2443,
7340 fidl::encoding::DynamicFlags::empty(),
7341 )
7342 }
7343
7344 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
7345 self.client.send::<NodeSetDebugClientInfoRequest>(
7346 (name, id),
7347 0x7275759070eb5ee2,
7348 fidl::encoding::DynamicFlags::empty(),
7349 )
7350 }
7351
7352 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
7353 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
7354 (deadline,),
7355 0x46d38f4772638867,
7356 fidl::encoding::DynamicFlags::empty(),
7357 )
7358 }
7359
7360 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7361 self.client.send::<fidl::encoding::EmptyPayload>(
7362 (),
7363 0x6bfbe2cf1701d288,
7364 fidl::encoding::DynamicFlags::empty(),
7365 )
7366 }
7367
7368 type GetNodeRefResponseFut =
7369 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
7370 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
7371 fn _decode(
7372 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7373 ) -> Result<fidl::Event, fidl::Error> {
7374 let _response = fidl::client::decode_transaction_body::<
7375 NodeGetNodeRefResponse,
7376 fidl::encoding::DefaultFuchsiaResourceDialect,
7377 0x467b7c75c35c3b84,
7378 >(_buf?)?;
7379 Ok(_response.node_ref)
7380 }
7381 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
7382 (),
7383 0x467b7c75c35c3b84,
7384 fidl::encoding::DynamicFlags::empty(),
7385 _decode,
7386 )
7387 }
7388
7389 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
7390 NodeIsAlternateForResult,
7391 fidl::encoding::DefaultFuchsiaResourceDialect,
7392 >;
7393 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
7394 fn _decode(
7395 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7396 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
7397 let _response = fidl::client::decode_transaction_body::<
7398 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
7399 fidl::encoding::DefaultFuchsiaResourceDialect,
7400 0x33a2a7aff2776c07,
7401 >(_buf?)?;
7402 Ok(_response.map(|x| x.is_alternate))
7403 }
7404 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
7405 (node_ref,),
7406 0x33a2a7aff2776c07,
7407 fidl::encoding::DynamicFlags::empty(),
7408 _decode,
7409 )
7410 }
7411
7412 fn r#create_child(
7413 &self,
7414 mut payload: BufferCollectionTokenGroupCreateChildRequest,
7415 ) -> Result<(), fidl::Error> {
7416 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
7417 &mut payload,
7418 0x2e74f8bcbf59ee59,
7419 fidl::encoding::DynamicFlags::empty(),
7420 )
7421 }
7422
7423 type CreateChildrenSyncResponseFut = fidl::client::QueryResponseFut<
7424 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7425 fidl::encoding::DefaultFuchsiaResourceDialect,
7426 >;
7427 fn r#create_children_sync(
7428 &self,
7429 mut rights_attenuation_masks: &[fidl::Rights],
7430 ) -> Self::CreateChildrenSyncResponseFut {
7431 fn _decode(
7432 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7433 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error>
7434 {
7435 let _response = fidl::client::decode_transaction_body::<
7436 BufferCollectionTokenGroupCreateChildrenSyncResponse,
7437 fidl::encoding::DefaultFuchsiaResourceDialect,
7438 0x569dc3ca2a98f535,
7439 >(_buf?)?;
7440 Ok(_response.tokens)
7441 }
7442 self.client.send_query_and_decode::<
7443 BufferCollectionTokenGroupCreateChildrenSyncRequest,
7444 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7445 >(
7446 (rights_attenuation_masks,),
7447 0x569dc3ca2a98f535,
7448 fidl::encoding::DynamicFlags::empty(),
7449 _decode,
7450 )
7451 }
7452
7453 fn r#all_children_present(&self) -> Result<(), fidl::Error> {
7454 self.client.send::<fidl::encoding::EmptyPayload>(
7455 (),
7456 0x1d41715f6f044b50,
7457 fidl::encoding::DynamicFlags::empty(),
7458 )
7459 }
7460}
7461
7462pub struct BufferCollectionTokenGroupEventStream {
7463 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
7464}
7465
7466impl std::marker::Unpin for BufferCollectionTokenGroupEventStream {}
7467
7468impl futures::stream::FusedStream for BufferCollectionTokenGroupEventStream {
7469 fn is_terminated(&self) -> bool {
7470 self.event_receiver.is_terminated()
7471 }
7472}
7473
7474impl futures::Stream for BufferCollectionTokenGroupEventStream {
7475 type Item = Result<BufferCollectionTokenGroupEvent, fidl::Error>;
7476
7477 fn poll_next(
7478 mut self: std::pin::Pin<&mut Self>,
7479 cx: &mut std::task::Context<'_>,
7480 ) -> std::task::Poll<Option<Self::Item>> {
7481 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
7482 &mut self.event_receiver,
7483 cx
7484 )?) {
7485 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenGroupEvent::decode(buf))),
7486 None => std::task::Poll::Ready(None),
7487 }
7488 }
7489}
7490
7491#[derive(Debug)]
7492pub enum BufferCollectionTokenGroupEvent {}
7493
7494impl BufferCollectionTokenGroupEvent {
7495 /// Decodes a message buffer as a [`BufferCollectionTokenGroupEvent`].
7496 fn decode(
7497 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
7498 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
7499 let (bytes, _handles) = buf.split_mut();
7500 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7501 debug_assert_eq!(tx_header.tx_id, 0);
7502 match tx_header.ordinal {
7503 _ => Err(fidl::Error::UnknownOrdinal {
7504 ordinal: tx_header.ordinal,
7505 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
7506 })
7507 }
7508 }
7509}
7510
7511/// A Stream of incoming requests for fuchsia.sysmem/BufferCollectionTokenGroup.
7512pub struct BufferCollectionTokenGroupRequestStream {
7513 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7514 is_terminated: bool,
7515}
7516
7517impl std::marker::Unpin for BufferCollectionTokenGroupRequestStream {}
7518
7519impl futures::stream::FusedStream for BufferCollectionTokenGroupRequestStream {
7520 fn is_terminated(&self) -> bool {
7521 self.is_terminated
7522 }
7523}
7524
7525impl fidl::endpoints::RequestStream for BufferCollectionTokenGroupRequestStream {
7526 type Protocol = BufferCollectionTokenGroupMarker;
7527 type ControlHandle = BufferCollectionTokenGroupControlHandle;
7528
7529 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
7530 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
7531 }
7532
7533 fn control_handle(&self) -> Self::ControlHandle {
7534 BufferCollectionTokenGroupControlHandle { inner: self.inner.clone() }
7535 }
7536
7537 fn into_inner(
7538 self,
7539 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
7540 {
7541 (self.inner, self.is_terminated)
7542 }
7543
7544 fn from_inner(
7545 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7546 is_terminated: bool,
7547 ) -> Self {
7548 Self { inner, is_terminated }
7549 }
7550}
7551
7552impl futures::Stream for BufferCollectionTokenGroupRequestStream {
7553 type Item = Result<BufferCollectionTokenGroupRequest, fidl::Error>;
7554
7555 fn poll_next(
7556 mut self: std::pin::Pin<&mut Self>,
7557 cx: &mut std::task::Context<'_>,
7558 ) -> std::task::Poll<Option<Self::Item>> {
7559 let this = &mut *self;
7560 if this.inner.check_shutdown(cx) {
7561 this.is_terminated = true;
7562 return std::task::Poll::Ready(None);
7563 }
7564 if this.is_terminated {
7565 panic!("polled BufferCollectionTokenGroupRequestStream after completion");
7566 }
7567 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
7568 |bytes, handles| {
7569 match this.inner.channel().read_etc(cx, bytes, handles) {
7570 std::task::Poll::Ready(Ok(())) => {}
7571 std::task::Poll::Pending => return std::task::Poll::Pending,
7572 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
7573 this.is_terminated = true;
7574 return std::task::Poll::Ready(None);
7575 }
7576 std::task::Poll::Ready(Err(e)) => {
7577 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
7578 e.into(),
7579 ))));
7580 }
7581 }
7582
7583 // A message has been received from the channel
7584 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7585
7586 std::task::Poll::Ready(Some(match header.ordinal {
7587 0x4577e238ae26291 => {
7588 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7589 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7590 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7591 let control_handle = BufferCollectionTokenGroupControlHandle {
7592 inner: this.inner.clone(),
7593 };
7594 Ok(BufferCollectionTokenGroupRequest::Sync {
7595 responder: BufferCollectionTokenGroupSyncResponder {
7596 control_handle: std::mem::ManuallyDrop::new(control_handle),
7597 tx_id: header.tx_id,
7598 },
7599 })
7600 }
7601 0x5b1d7a4f5681fca7 => {
7602 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7603 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7604 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7605 let control_handle = BufferCollectionTokenGroupControlHandle {
7606 inner: this.inner.clone(),
7607 };
7608 Ok(BufferCollectionTokenGroupRequest::Close {
7609 control_handle,
7610 })
7611 }
7612 0x77a41bb6217e2443 => {
7613 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7614 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7615 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
7616 let control_handle = BufferCollectionTokenGroupControlHandle {
7617 inner: this.inner.clone(),
7618 };
7619 Ok(BufferCollectionTokenGroupRequest::SetName {priority: req.priority,
7620name: req.name,
7621
7622 control_handle,
7623 })
7624 }
7625 0x7275759070eb5ee2 => {
7626 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7627 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7628 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
7629 let control_handle = BufferCollectionTokenGroupControlHandle {
7630 inner: this.inner.clone(),
7631 };
7632 Ok(BufferCollectionTokenGroupRequest::SetDebugClientInfo {name: req.name,
7633id: req.id,
7634
7635 control_handle,
7636 })
7637 }
7638 0x46d38f4772638867 => {
7639 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7640 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7641 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
7642 let control_handle = BufferCollectionTokenGroupControlHandle {
7643 inner: this.inner.clone(),
7644 };
7645 Ok(BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {deadline: req.deadline,
7646
7647 control_handle,
7648 })
7649 }
7650 0x6bfbe2cf1701d288 => {
7651 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7652 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7653 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7654 let control_handle = BufferCollectionTokenGroupControlHandle {
7655 inner: this.inner.clone(),
7656 };
7657 Ok(BufferCollectionTokenGroupRequest::SetVerboseLogging {
7658 control_handle,
7659 })
7660 }
7661 0x467b7c75c35c3b84 => {
7662 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7663 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7664 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7665 let control_handle = BufferCollectionTokenGroupControlHandle {
7666 inner: this.inner.clone(),
7667 };
7668 Ok(BufferCollectionTokenGroupRequest::GetNodeRef {
7669 responder: BufferCollectionTokenGroupGetNodeRefResponder {
7670 control_handle: std::mem::ManuallyDrop::new(control_handle),
7671 tx_id: header.tx_id,
7672 },
7673 })
7674 }
7675 0x33a2a7aff2776c07 => {
7676 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7677 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7678 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
7679 let control_handle = BufferCollectionTokenGroupControlHandle {
7680 inner: this.inner.clone(),
7681 };
7682 Ok(BufferCollectionTokenGroupRequest::IsAlternateFor {node_ref: req.node_ref,
7683
7684 responder: BufferCollectionTokenGroupIsAlternateForResponder {
7685 control_handle: std::mem::ManuallyDrop::new(control_handle),
7686 tx_id: header.tx_id,
7687 },
7688 })
7689 }
7690 0x2e74f8bcbf59ee59 => {
7691 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7692 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7693 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildRequest>(&header, _body_bytes, handles, &mut req)?;
7694 let control_handle = BufferCollectionTokenGroupControlHandle {
7695 inner: this.inner.clone(),
7696 };
7697 Ok(BufferCollectionTokenGroupRequest::CreateChild {payload: req,
7698 control_handle,
7699 })
7700 }
7701 0x569dc3ca2a98f535 => {
7702 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7703 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildrenSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7704 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildrenSyncRequest>(&header, _body_bytes, handles, &mut req)?;
7705 let control_handle = BufferCollectionTokenGroupControlHandle {
7706 inner: this.inner.clone(),
7707 };
7708 Ok(BufferCollectionTokenGroupRequest::CreateChildrenSync {rights_attenuation_masks: req.rights_attenuation_masks,
7709
7710 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder {
7711 control_handle: std::mem::ManuallyDrop::new(control_handle),
7712 tx_id: header.tx_id,
7713 },
7714 })
7715 }
7716 0x1d41715f6f044b50 => {
7717 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7718 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7719 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7720 let control_handle = BufferCollectionTokenGroupControlHandle {
7721 inner: this.inner.clone(),
7722 };
7723 Ok(BufferCollectionTokenGroupRequest::AllChildrenPresent {
7724 control_handle,
7725 })
7726 }
7727 _ => Err(fidl::Error::UnknownOrdinal {
7728 ordinal: header.ordinal,
7729 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
7730 }),
7731 }))
7732 },
7733 )
7734 }
7735}
7736
7737/// The sysmem implementation is guaranteed to be consistent with a logical /
7738/// conceptual model as follows:
7739///
7740/// As usual, a logical allocation considers either the root and all nodes with
7741/// connectivity to the root that don't transit an AttachToken(), or a sub-tree
7742/// rooted at an AttachToken() token and all nodes with connectivity to that
7743/// subtree that don't transit another AttachToken(). This is called the
7744/// logical allocation pruned sub-tree, or pruned sub-tree for short.
7745///
7746/// During constraints aggregation, each BufferCollectionTokenGroup will select
7747/// a single child token among its children. The rest of the children will
7748/// appear to fail the logical allocation, while the selected child may succeed.
7749///
7750/// When more than one BufferCollectionTokenGroup exists in the overall logical
7751/// allocation pruned sub-tree, the relative priority between two groups is
7752/// equivalent to their ordering in a DFS pre-order iteration of the tree, with
7753/// parents higher priority than children, and left children higher priority
7754/// than right children.
7755///
7756/// When a particular child of a group is selected (whether provisionally during
7757/// a constraints aggregation attempt, or as a final selection), the
7758/// non-selection of other children of the group can potentially "hide" other
7759/// groups under those non-selected children.
7760///
7761/// Within a logical allocation, aggregation is attempted first by provisionally
7762/// selecting the child 0 of the highest-priority group, and child 0 of the next
7763/// highest-priority group that isn't hidden by the provisional selections so
7764/// far, etc.
7765///
7766/// If that aggregation attempt fails, aggregation will be attempted with the
7767/// ordinal 0 child of all the same groups except the lowest priority non-hidden
7768/// group which will provisionally select its ordinal 1 child (and then child 2
7769/// and so on). If a new lowest-priority group is un-hidden as provisional
7770/// selections are updated, that newly un-hidden lowest-priority group has all
7771/// its children considered in order, before changing the provisional selection
7772/// in the former lowest-priority group. In terms of result, this is equivalent
7773/// to systematic enumeration of all possible combinations of choices in a
7774/// counting-like order updating the lowest-priority group the most often and
7775/// the highest-priority group the least often. Rather than actually attempting
7776/// aggregation with all the combinations, we can skip over combinations which
7777/// are redundant/equivalent due to hiding without any change to the result.
7778///
7779/// Attempted aggregations of enumerated non-equivalent combinations of choices
7780/// continue in this manner until either (a) all aggregation attempts fail in
7781/// which case the overall logical allocation fails, or (b) until an attempted
7782/// aggregation succeeds, in which case buffer allocation (if needed) is
7783/// attempted once. If buffer allocation based on the first successful
7784/// aggregation fails, the overall logical allocation fails (there is no buffer
7785/// allocation retry / re-attempt). If buffer allocation succeeds (or is not
7786/// needed), the logical allocation succeeds.
7787///
7788/// If this prioritization scheme cannot reasonably work for your usage of
7789/// sysmem, please contact sysmem folks to discuss potentially adding a way to
7790/// achieve what you need.
7791///
7792/// Please avoid creating a large number of BufferCollectionTokenGroup(s) per
7793/// logical allocation, especially with large number of children overall, and
7794/// especially in cases where aggregation may reasonably be expected to often
7795/// fail using ordinal 0 children and possibly with later children as well. We
7796/// anticipate mitigating potentially high time complexity of evaluating too
7797/// many child combinations/selections across too many groups by simply failing
7798/// logical allocation beyond a certain (fairly high, but not huge) max number
7799/// of considered group child combinations/selections. More advanced (and more
7800/// complicated) mitigation is not anticipated to be practically necessary or
7801/// worth the added complexity. Please contact sysmem folks if the max limit
7802/// is getting hit or if you anticipate it getting hit, to discuss potential
7803/// options.
7804///
7805/// Prefer to use multiple ImageFormatConstraints in a single
7806/// BufferCollectionConstraints when feasible (when a participant just needs to
7807/// express the ability to work with more than a single PixelFormat, with
7808/// sysmem choosing which PixelFormat to use among those supported by all
7809/// participants).
7810///
7811/// Similar to BufferCollectionToken and BufferCollection, closure of the
7812/// BufferCollectionTokenGroup channel without sending Close() first will cause
7813/// logical buffer collection failure (or sub-tree failure if using
7814/// SetDispensable() or AttachToken() and the BufferCollectionTokenGroup is part
7815/// of a sub-tree under such a node that doesn't propagate failure to its
7816/// parent).
7817#[derive(Debug)]
7818pub enum BufferCollectionTokenGroupRequest {
7819 /// Ensure that previous messages, including Duplicate() messages on a
7820 /// token, collection, or group, have been received server side.
7821 ///
7822 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
7823 /// valid sysmem token risks the Sync() hanging forever. See
7824 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
7825 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
7826 /// Another way is to pass the token to BindSharedCollection(), which also
7827 /// validates the token as part of exchanging it for a BufferCollection
7828 /// channel, and BufferCollection Sync() can then be used.
7829 ///
7830 /// After a Sync(), it's then safe to send the client end of token_request
7831 /// to another participant knowing the server will recognize the token when
7832 /// it's sent into BindSharedCollection() by the other participant.
7833 ///
7834 /// Other options include waiting for each token.Duplicate() to complete
7835 /// individually (using separate call to token.Sync() after each), or
7836 /// calling Sync() on BufferCollection after the token has been turned in
7837 /// via BindSharedCollection().
7838 ///
7839 /// Another way to mitigate is to avoid calling Sync() on the token, and
7840 /// instead later deal with potential failure of BufferCollection.Sync() if
7841 /// the original token was invalid. This option can be preferable from a
7842 /// performance point of view, but requires client code to delay sending
7843 /// tokens duplicated from this token until after client code has converted
7844 /// the duplicating token to a BufferCollection and received successful
7845 /// response from BufferCollection.Sync().
7846 ///
7847 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
7848 /// When BufferCollection.Sync() isn't feasible, the caller must already
7849 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
7850 /// hang forever. See ValidateBufferCollectionToken() to check token
7851 /// validity first if the token isn't already known to be (is/was) valid.
7852 Sync { responder: BufferCollectionTokenGroupSyncResponder },
7853 /// On a BufferCollectionToken channel:
7854 ///
7855 /// Normally a participant will convert a BufferCollectionToken into a
7856 /// BufferCollection view, but a participant is also free to Close() the
7857 /// token (and then close the channel immediately or shortly later in
7858 /// response to server closing its end), which avoids causing logical buffer
7859 /// collection failure. Â Normally an unexpected token channel close will
7860 /// cause logical buffer collection failure (the only exceptions being
7861 /// certain cases involving AttachToken() or SetDispensable()).
7862 ///
7863 /// On a BufferCollection channel:
7864 ///
7865 /// By default the server handles unexpected failure of a BufferCollection
7866 /// by failing the whole logical buffer collection. Partly this is to
7867 /// expedite closing VMO handles to reclaim memory when any participant
7868 /// fails. If a participant would like to cleanly close a BufferCollection
7869 /// view without causing logical buffer collection failure, the participant
7870 /// can send Close() before closing the client end of the BufferCollection
7871 /// channel. If this is the last BufferCollection view, the logical buffer
7872 /// collection will still go away. The Close() can occur before or after
7873 /// SetConstraints(). If before SetConstraints(), the buffer collection
7874 /// won't require constraints from this node in order to allocate. If
7875 /// after SetConstraints(), the constraints are retained and aggregated
7876 /// along with any subsequent logical allocation(s), despite the lack of
7877 /// channel connection.
7878 ///
7879 /// On a BufferCollectionTokenGroup channel:
7880 ///
7881 /// By default, unexpected failure of a BufferCollectionTokenGroup will
7882 /// trigger failure of the logical BufferCollectionTokenGroup and will
7883 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
7884 /// channel without failing the logical group or propagating failure, send
7885 /// Close() before closing the channel client endpoint.
7886 ///
7887 /// If Close() occurs before AllChildrenPresent(), the logical buffer
7888 /// collection will still fail despite the Close() (because sysmem can't be
7889 /// sure whether all relevant children were created, so it's ambiguous
7890 /// whether all relevant constraints will be provided to sysmem). If
7891 /// Close() occurs after AllChildrenPresent(), the children and all their
7892 /// constraints remain intact (just as they would if the
7893 /// BufferCollectionTokenGroup channel had remained open), and the close
7894 /// doesn't trigger or propagate failure.
7895 Close { control_handle: BufferCollectionTokenGroupControlHandle },
7896 /// Set a name for VMOs in this buffer collection. The name may be truncated
7897 /// shorter. The name only affects VMOs allocated after it's set - this call
7898 /// does not rename existing VMOs. If multiple clients set different names
7899 /// then the larger priority value will win.
7900 SetName { priority: u32, name: String, control_handle: BufferCollectionTokenGroupControlHandle },
7901 /// Set information about the current client that can be used by sysmem to
7902 /// help debug leaking memory and hangs waiting for constraints. |name| can
7903 /// be an arbitrary string, but the current process name (see
7904 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
7905 /// arbitrary id, but the current process ID (see
7906 /// fsl::GetCurrentProcessKoid()) is a good default.
7907 ///
7908 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
7909 /// indicate which client is closing their channel first, leading to
7910 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
7911 /// over, but if happening earlier than expected, the
7912 /// client-channel-specific name can help diagnose where the failure is
7913 /// first coming from, from sysmem's point of view).
7914 ///
7915 /// By default (unless overriden by this message or using
7916 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
7917 /// parent Node at the time the child Node is created. While this can be
7918 /// better than nothing, it's often better for each participant to use
7919 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
7920 /// info directly relevant to the current client. Also, SetVerboseLogging()
7921 /// can be used to help disambiguate if a Node is suspected of having info
7922 /// that was copied from its parent.
7923 SetDebugClientInfo {
7924 name: String,
7925 id: u64,
7926 control_handle: BufferCollectionTokenGroupControlHandle,
7927 },
7928 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
7929 /// after creating a collection. Clients can call this method to change
7930 /// when the log is printed. If multiple client set the deadline, it's
7931 /// unspecified which deadline will take effect.
7932 SetDebugTimeoutLogDeadline {
7933 deadline: i64,
7934 control_handle: BufferCollectionTokenGroupControlHandle,
7935 },
7936 /// Verbose logging includes constraints set via SetConstraints() from each
7937 /// client along with info set via SetDebugClientInfo() and the structure of
7938 /// the tree of Node(s).
7939 ///
7940 /// Normally sysmem prints only a single line complaint when aggregation
7941 /// fails, with just the specific detailed reason that aggregation failed,
7942 /// with minimal context. While this is often enough to diagnose a problem
7943 /// if only a small change was made and the system had been working before
7944 /// the small change, it's often not particularly helpful for getting a new
7945 /// buffer collection to work for the first time. Especially with more
7946 /// complex trees of nodes, involving things like AttachToken(),
7947 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
7948 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
7949 /// looks like and why it's failing a logical allocation, or why a tree or
7950 /// sub-tree is failing sooner than expected.
7951 ///
7952 /// The intent of the extra logging is to be acceptable from a performance
7953 /// point of view, if only enabled on a low number of buffer collections.
7954 /// If we're not tracking down a bug, we shouldn't send this message.
7955 ///
7956 /// If too many participants leave verbose logging enabled, we may end up
7957 /// needing to require that system-wide sysmem verbose logging be permitted
7958 /// via some other setting, to avoid sysmem spamming the log too much due to
7959 /// this message.
7960 ///
7961 /// This may be a NOP for some nodes due to intentional policy associated
7962 /// with the node, if we don't trust a node enough to let it turn on verbose
7963 /// logging.
7964 SetVerboseLogging { control_handle: BufferCollectionTokenGroupControlHandle },
7965 /// This gets an event handle that can be used as a parameter to
7966 /// IsAlternateFor() called on any Node. The client will not be granted the
7967 /// right to signal this event, as this handle should only be used as proof
7968 /// that the client obtained this handle from this Node.
7969 ///
7970 /// Because this is a get not a set, no Sync() is needed between the
7971 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
7972 /// potentially being on different channels.
7973 ///
7974 /// See also IsAlternateFor().
7975 GetNodeRef { responder: BufferCollectionTokenGroupGetNodeRefResponder },
7976 /// This checks whether the calling node is in a subtree rooted at a
7977 /// different child token of a common parent BufferCollectionTokenGroup, in
7978 /// relation to the passed-in node_ref.
7979 ///
7980 /// This call is for assisting with admission control de-duplication, and
7981 /// with debugging.
7982 ///
7983 /// The node_ref must be obtained using GetNodeRef() of a
7984 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
7985 ///
7986 /// The node_ref can be a duplicated handle; it's not necessary to call
7987 /// GetNodeRef() for every call to IsAlternateFor().
7988 ///
7989 /// If a calling token may not actually be a valid token at all due to
7990 /// a potentially hostile/untrusted provider of the token, call
7991 /// ValidateBufferCollectionToken() first instead of potentially getting
7992 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
7993 /// token not being a real token (not really talking to sysmem). Another
7994 /// option is to call BindSharedCollection with this token first which also
7995 /// validates the token along with converting it to a BufferCollection, then
7996 /// call BufferCollection IsAlternateFor().
7997 ///
7998 /// error values:
7999 ///
8000 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
8001 /// buffer collection as the calling Node. Before logical allocation and
8002 /// within the same logical allocation sub-tree, this essentially means that
8003 /// the node_ref was never part of this logical buffer collection, since
8004 /// before logical allocation all node_refs that come into existence remain
8005 /// in existence at least until logical allocation (including Node(s) that
8006 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
8007 /// to be returned, this Node's channel needs to still be connected server
8008 /// side, which won't be the case if the whole logical allocation has
8009 /// failed. After logical allocation or in a different logical allocation
8010 /// sub-tree there are additional potential reasons for this error. For
8011 /// example a different logical allocation (separated from this Node(s)
8012 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
8013 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
8014 /// exist and may select a different child sub-tree than the sub-tree the
8015 /// node_ref is in causing deletion of the node_ref Node. The only time
8016 /// sysmem keeps a Node around after that Node has no corresponding channel
8017 /// is when Close() is used and the Node's sub-tree has not yet failed.
8018 /// Another reason for this error is if the node_ref is an eventpair handle
8019 /// with sufficient rights, but isn't actually a real node_ref obtained from
8020 /// GetNodeRef().
8021 ///
8022 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
8023 /// eventpair handle, or doesn't have the needed rights expected on a real
8024 /// node_ref.
8025 ///
8026 /// No other failing status codes are returned by this call. However,
8027 /// sysmem may add additional codes in future, so the client should have
8028 /// sensible default handling for any failing status code.
8029 ///
8030 /// On success, is_alternate has the following meaning:
8031 /// * true - The first parent node in common between the calling node and
8032 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
8033 /// the calling Node and the node_ref Node will _not_ have both their
8034 /// constraints apply - rather sysmem will choose one or the other of
8035 /// the constraints - never both. This is because only one child of
8036 /// a BufferCollectionTokenGroup is selected during logical allocation,
8037 /// with only that one child's sub-tree contributing to constraints
8038 /// aggregation.
8039 /// * false - The first parent node in common between the calling Node and
8040 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
8041 /// this means the first parent node in common is a
8042 /// BufferCollectionToken or BufferCollection (regardless of not
8043 /// Close()ed or Close()ed). This means that the calling Node and the
8044 /// node_ref Node _may_ have both their constraints apply during
8045 /// constraints aggregation of the logical allocation, if both Node(s)
8046 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
8047 /// In this case, there is no BufferCollectionTokenGroup that will
8048 /// directly prevent the two Node(s) from both being selected and their
8049 /// constraints both aggregated, but even when false, one or both
8050 /// Node(s) may still be eliminated from consideration if one or both
8051 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
8052 /// which selects a child sub-tree other than the sub-tree containing
8053 /// the calling Node or node_ref Node.
8054 IsAlternateFor {
8055 node_ref: fidl::Event,
8056 responder: BufferCollectionTokenGroupIsAlternateForResponder,
8057 },
8058 /// Create a child token. Before passing the client end of this token to
8059 /// BindSharedCollection(), completion of Sync() after CreateChild() is
8060 /// required. Or the client can use CreateChildrenSync() which essentially
8061 /// includes the Sync().
8062 ///
8063 /// token_request - the server end of the new token channel.
8064 ///
8065 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
8066 /// allows the holder to get the same rights to buffers as the parent token
8067 /// (of the group) had.
8068 CreateChild {
8069 payload: BufferCollectionTokenGroupCreateChildRequest,
8070 control_handle: BufferCollectionTokenGroupControlHandle,
8071 },
8072 /// Create 1 or more child tokens at once, synchronously. In contrast to
8073 /// CreateChild(), no Sync() completion is required before passing the
8074 /// client end of a returned token to BindSharedCollection().
8075 ///
8076 /// The size of the rights_attentuation_mask determines the number of
8077 /// created child tokens.
8078 ///
8079 /// The lower-index child tokens are higher priority (attempted sooner) than
8080 /// higher-index child tokens.
8081 ///
8082 /// As per all child tokens, successful aggregation will choose exactly one
8083 /// child among all created children (across all children created across
8084 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
8085 ///
8086 /// The maximum permissible total number of children per group, and total
8087 /// number of nodes in an overall tree (from the root) are capped to limits
8088 /// which are not configurable via these protocols.
8089 CreateChildrenSync {
8090 rights_attenuation_masks: Vec<fidl::Rights>,
8091 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder,
8092 },
8093 /// AllChildrenPresent()
8094 ///
8095 /// After creating all children, the client must call AllChildrenPresent()
8096 /// to inform sysmem that no more children will be created, so that sysmem
8097 /// can know when it's ok to start aggregating constraints.
8098 ///
8099 /// If Close() is to be sent, it should be sent _after_
8100 /// AllChildrenPresent(), else failure of the group and propagation of the
8101 /// failure to the group's parent will still be triggered.
8102 AllChildrenPresent { control_handle: BufferCollectionTokenGroupControlHandle },
8103}
8104
8105impl BufferCollectionTokenGroupRequest {
8106 #[allow(irrefutable_let_patterns)]
8107 pub fn into_sync(self) -> Option<(BufferCollectionTokenGroupSyncResponder)> {
8108 if let BufferCollectionTokenGroupRequest::Sync { responder } = self {
8109 Some((responder))
8110 } else {
8111 None
8112 }
8113 }
8114
8115 #[allow(irrefutable_let_patterns)]
8116 pub fn into_close(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8117 if let BufferCollectionTokenGroupRequest::Close { control_handle } = self {
8118 Some((control_handle))
8119 } else {
8120 None
8121 }
8122 }
8123
8124 #[allow(irrefutable_let_patterns)]
8125 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionTokenGroupControlHandle)> {
8126 if let BufferCollectionTokenGroupRequest::SetName { priority, name, control_handle } = self
8127 {
8128 Some((priority, name, control_handle))
8129 } else {
8130 None
8131 }
8132 }
8133
8134 #[allow(irrefutable_let_patterns)]
8135 pub fn into_set_debug_client_info(
8136 self,
8137 ) -> Option<(String, u64, BufferCollectionTokenGroupControlHandle)> {
8138 if let BufferCollectionTokenGroupRequest::SetDebugClientInfo { name, id, control_handle } =
8139 self
8140 {
8141 Some((name, id, control_handle))
8142 } else {
8143 None
8144 }
8145 }
8146
8147 #[allow(irrefutable_let_patterns)]
8148 pub fn into_set_debug_timeout_log_deadline(
8149 self,
8150 ) -> Option<(i64, BufferCollectionTokenGroupControlHandle)> {
8151 if let BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {
8152 deadline,
8153 control_handle,
8154 } = self
8155 {
8156 Some((deadline, control_handle))
8157 } else {
8158 None
8159 }
8160 }
8161
8162 #[allow(irrefutable_let_patterns)]
8163 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8164 if let BufferCollectionTokenGroupRequest::SetVerboseLogging { control_handle } = self {
8165 Some((control_handle))
8166 } else {
8167 None
8168 }
8169 }
8170
8171 #[allow(irrefutable_let_patterns)]
8172 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGroupGetNodeRefResponder)> {
8173 if let BufferCollectionTokenGroupRequest::GetNodeRef { responder } = self {
8174 Some((responder))
8175 } else {
8176 None
8177 }
8178 }
8179
8180 #[allow(irrefutable_let_patterns)]
8181 pub fn into_is_alternate_for(
8182 self,
8183 ) -> Option<(fidl::Event, BufferCollectionTokenGroupIsAlternateForResponder)> {
8184 if let BufferCollectionTokenGroupRequest::IsAlternateFor { node_ref, responder } = self {
8185 Some((node_ref, responder))
8186 } else {
8187 None
8188 }
8189 }
8190
8191 #[allow(irrefutable_let_patterns)]
8192 pub fn into_create_child(
8193 self,
8194 ) -> Option<(
8195 BufferCollectionTokenGroupCreateChildRequest,
8196 BufferCollectionTokenGroupControlHandle,
8197 )> {
8198 if let BufferCollectionTokenGroupRequest::CreateChild { payload, control_handle } = self {
8199 Some((payload, control_handle))
8200 } else {
8201 None
8202 }
8203 }
8204
8205 #[allow(irrefutable_let_patterns)]
8206 pub fn into_create_children_sync(
8207 self,
8208 ) -> Option<(Vec<fidl::Rights>, BufferCollectionTokenGroupCreateChildrenSyncResponder)> {
8209 if let BufferCollectionTokenGroupRequest::CreateChildrenSync {
8210 rights_attenuation_masks,
8211 responder,
8212 } = self
8213 {
8214 Some((rights_attenuation_masks, responder))
8215 } else {
8216 None
8217 }
8218 }
8219
8220 #[allow(irrefutable_let_patterns)]
8221 pub fn into_all_children_present(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8222 if let BufferCollectionTokenGroupRequest::AllChildrenPresent { control_handle } = self {
8223 Some((control_handle))
8224 } else {
8225 None
8226 }
8227 }
8228
8229 /// Name of the method defined in FIDL
8230 pub fn method_name(&self) -> &'static str {
8231 match *self {
8232 BufferCollectionTokenGroupRequest::Sync { .. } => "sync",
8233 BufferCollectionTokenGroupRequest::Close { .. } => "close",
8234 BufferCollectionTokenGroupRequest::SetName { .. } => "set_name",
8235 BufferCollectionTokenGroupRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
8236 BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline { .. } => {
8237 "set_debug_timeout_log_deadline"
8238 }
8239 BufferCollectionTokenGroupRequest::SetVerboseLogging { .. } => "set_verbose_logging",
8240 BufferCollectionTokenGroupRequest::GetNodeRef { .. } => "get_node_ref",
8241 BufferCollectionTokenGroupRequest::IsAlternateFor { .. } => "is_alternate_for",
8242 BufferCollectionTokenGroupRequest::CreateChild { .. } => "create_child",
8243 BufferCollectionTokenGroupRequest::CreateChildrenSync { .. } => "create_children_sync",
8244 BufferCollectionTokenGroupRequest::AllChildrenPresent { .. } => "all_children_present",
8245 }
8246 }
8247}
8248
8249#[derive(Debug, Clone)]
8250pub struct BufferCollectionTokenGroupControlHandle {
8251 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
8252}
8253
8254impl fidl::endpoints::ControlHandle for BufferCollectionTokenGroupControlHandle {
8255 fn shutdown(&self) {
8256 self.inner.shutdown()
8257 }
8258
8259 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
8260 self.inner.shutdown_with_epitaph(status)
8261 }
8262
8263 fn is_closed(&self) -> bool {
8264 self.inner.channel().is_closed()
8265 }
8266 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
8267 self.inner.channel().on_closed()
8268 }
8269
8270 #[cfg(target_os = "fuchsia")]
8271 fn signal_peer(
8272 &self,
8273 clear_mask: zx::Signals,
8274 set_mask: zx::Signals,
8275 ) -> Result<(), zx_status::Status> {
8276 use fidl::Peered;
8277 self.inner.channel().signal_peer(clear_mask, set_mask)
8278 }
8279}
8280
8281impl BufferCollectionTokenGroupControlHandle {}
8282
8283#[must_use = "FIDL methods require a response to be sent"]
8284#[derive(Debug)]
8285pub struct BufferCollectionTokenGroupSyncResponder {
8286 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8287 tx_id: u32,
8288}
8289
8290/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8291/// if the responder is dropped without sending a response, so that the client
8292/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8293impl std::ops::Drop for BufferCollectionTokenGroupSyncResponder {
8294 fn drop(&mut self) {
8295 self.control_handle.shutdown();
8296 // Safety: drops once, never accessed again
8297 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8298 }
8299}
8300
8301impl fidl::endpoints::Responder for BufferCollectionTokenGroupSyncResponder {
8302 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8303
8304 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8305 &self.control_handle
8306 }
8307
8308 fn drop_without_shutdown(mut self) {
8309 // Safety: drops once, never accessed again due to mem::forget
8310 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8311 // Prevent Drop from running (which would shut down the channel)
8312 std::mem::forget(self);
8313 }
8314}
8315
8316impl BufferCollectionTokenGroupSyncResponder {
8317 /// Sends a response to the FIDL transaction.
8318 ///
8319 /// Sets the channel to shutdown if an error occurs.
8320 pub fn send(self) -> Result<(), fidl::Error> {
8321 let _result = self.send_raw();
8322 if _result.is_err() {
8323 self.control_handle.shutdown();
8324 }
8325 self.drop_without_shutdown();
8326 _result
8327 }
8328
8329 /// Similar to "send" but does not shutdown the channel if an error occurs.
8330 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
8331 let _result = self.send_raw();
8332 self.drop_without_shutdown();
8333 _result
8334 }
8335
8336 fn send_raw(&self) -> Result<(), fidl::Error> {
8337 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
8338 (),
8339 self.tx_id,
8340 0x4577e238ae26291,
8341 fidl::encoding::DynamicFlags::empty(),
8342 )
8343 }
8344}
8345
8346#[must_use = "FIDL methods require a response to be sent"]
8347#[derive(Debug)]
8348pub struct BufferCollectionTokenGroupGetNodeRefResponder {
8349 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8350 tx_id: u32,
8351}
8352
8353/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8354/// if the responder is dropped without sending a response, so that the client
8355/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8356impl std::ops::Drop for BufferCollectionTokenGroupGetNodeRefResponder {
8357 fn drop(&mut self) {
8358 self.control_handle.shutdown();
8359 // Safety: drops once, never accessed again
8360 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8361 }
8362}
8363
8364impl fidl::endpoints::Responder for BufferCollectionTokenGroupGetNodeRefResponder {
8365 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8366
8367 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8368 &self.control_handle
8369 }
8370
8371 fn drop_without_shutdown(mut self) {
8372 // Safety: drops once, never accessed again due to mem::forget
8373 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8374 // Prevent Drop from running (which would shut down the channel)
8375 std::mem::forget(self);
8376 }
8377}
8378
8379impl BufferCollectionTokenGroupGetNodeRefResponder {
8380 /// Sends a response to the FIDL transaction.
8381 ///
8382 /// Sets the channel to shutdown if an error occurs.
8383 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8384 let _result = self.send_raw(node_ref);
8385 if _result.is_err() {
8386 self.control_handle.shutdown();
8387 }
8388 self.drop_without_shutdown();
8389 _result
8390 }
8391
8392 /// Similar to "send" but does not shutdown the channel if an error occurs.
8393 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8394 let _result = self.send_raw(node_ref);
8395 self.drop_without_shutdown();
8396 _result
8397 }
8398
8399 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8400 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
8401 (node_ref,),
8402 self.tx_id,
8403 0x467b7c75c35c3b84,
8404 fidl::encoding::DynamicFlags::empty(),
8405 )
8406 }
8407}
8408
8409#[must_use = "FIDL methods require a response to be sent"]
8410#[derive(Debug)]
8411pub struct BufferCollectionTokenGroupIsAlternateForResponder {
8412 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8413 tx_id: u32,
8414}
8415
8416/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8417/// if the responder is dropped without sending a response, so that the client
8418/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8419impl std::ops::Drop for BufferCollectionTokenGroupIsAlternateForResponder {
8420 fn drop(&mut self) {
8421 self.control_handle.shutdown();
8422 // Safety: drops once, never accessed again
8423 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8424 }
8425}
8426
8427impl fidl::endpoints::Responder for BufferCollectionTokenGroupIsAlternateForResponder {
8428 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8429
8430 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8431 &self.control_handle
8432 }
8433
8434 fn drop_without_shutdown(mut self) {
8435 // Safety: drops once, never accessed again due to mem::forget
8436 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8437 // Prevent Drop from running (which would shut down the channel)
8438 std::mem::forget(self);
8439 }
8440}
8441
8442impl BufferCollectionTokenGroupIsAlternateForResponder {
8443 /// Sends a response to the FIDL transaction.
8444 ///
8445 /// Sets the channel to shutdown if an error occurs.
8446 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8447 let _result = self.send_raw(result);
8448 if _result.is_err() {
8449 self.control_handle.shutdown();
8450 }
8451 self.drop_without_shutdown();
8452 _result
8453 }
8454
8455 /// Similar to "send" but does not shutdown the channel if an error occurs.
8456 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8457 let _result = self.send_raw(result);
8458 self.drop_without_shutdown();
8459 _result
8460 }
8461
8462 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8463 self.control_handle
8464 .inner
8465 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
8466 result.map(|is_alternate| (is_alternate,)),
8467 self.tx_id,
8468 0x33a2a7aff2776c07,
8469 fidl::encoding::DynamicFlags::empty(),
8470 )
8471 }
8472}
8473
8474#[must_use = "FIDL methods require a response to be sent"]
8475#[derive(Debug)]
8476pub struct BufferCollectionTokenGroupCreateChildrenSyncResponder {
8477 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8478 tx_id: u32,
8479}
8480
8481/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8482/// if the responder is dropped without sending a response, so that the client
8483/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8484impl std::ops::Drop for BufferCollectionTokenGroupCreateChildrenSyncResponder {
8485 fn drop(&mut self) {
8486 self.control_handle.shutdown();
8487 // Safety: drops once, never accessed again
8488 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8489 }
8490}
8491
8492impl fidl::endpoints::Responder for BufferCollectionTokenGroupCreateChildrenSyncResponder {
8493 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8494
8495 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8496 &self.control_handle
8497 }
8498
8499 fn drop_without_shutdown(mut self) {
8500 // Safety: drops once, never accessed again due to mem::forget
8501 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8502 // Prevent Drop from running (which would shut down the channel)
8503 std::mem::forget(self);
8504 }
8505}
8506
8507impl BufferCollectionTokenGroupCreateChildrenSyncResponder {
8508 /// Sends a response to the FIDL transaction.
8509 ///
8510 /// Sets the channel to shutdown if an error occurs.
8511 pub fn send(
8512 self,
8513 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8514 ) -> Result<(), fidl::Error> {
8515 let _result = self.send_raw(tokens);
8516 if _result.is_err() {
8517 self.control_handle.shutdown();
8518 }
8519 self.drop_without_shutdown();
8520 _result
8521 }
8522
8523 /// Similar to "send" but does not shutdown the channel if an error occurs.
8524 pub fn send_no_shutdown_on_err(
8525 self,
8526 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8527 ) -> Result<(), fidl::Error> {
8528 let _result = self.send_raw(tokens);
8529 self.drop_without_shutdown();
8530 _result
8531 }
8532
8533 fn send_raw(
8534 &self,
8535 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8536 ) -> Result<(), fidl::Error> {
8537 self.control_handle.inner.send::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(
8538 (tokens.as_mut(),),
8539 self.tx_id,
8540 0x569dc3ca2a98f535,
8541 fidl::encoding::DynamicFlags::empty(),
8542 )
8543 }
8544}
8545
8546#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
8547pub struct NodeMarker;
8548
8549impl fidl::endpoints::ProtocolMarker for NodeMarker {
8550 type Proxy = NodeProxy;
8551 type RequestStream = NodeRequestStream;
8552 #[cfg(target_os = "fuchsia")]
8553 type SynchronousProxy = NodeSynchronousProxy;
8554
8555 const DEBUG_NAME: &'static str = "(anonymous) Node";
8556}
8557pub type NodeIsAlternateForResult = Result<bool, i32>;
8558
8559pub trait NodeProxyInterface: Send + Sync {
8560 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
8561 fn r#sync(&self) -> Self::SyncResponseFut;
8562 fn r#close(&self) -> Result<(), fidl::Error>;
8563 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
8564 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
8565 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
8566 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
8567 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
8568 + Send;
8569 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
8570 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
8571 + Send;
8572 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
8573}
8574#[derive(Debug)]
8575#[cfg(target_os = "fuchsia")]
8576pub struct NodeSynchronousProxy {
8577 client: fidl::client::sync::Client,
8578}
8579
8580#[cfg(target_os = "fuchsia")]
8581impl fidl::endpoints::SynchronousProxy for NodeSynchronousProxy {
8582 type Proxy = NodeProxy;
8583 type Protocol = NodeMarker;
8584
8585 fn from_channel(inner: fidl::Channel) -> Self {
8586 Self::new(inner)
8587 }
8588
8589 fn into_channel(self) -> fidl::Channel {
8590 self.client.into_channel()
8591 }
8592
8593 fn as_channel(&self) -> &fidl::Channel {
8594 self.client.as_channel()
8595 }
8596}
8597
8598#[cfg(target_os = "fuchsia")]
8599impl NodeSynchronousProxy {
8600 pub fn new(channel: fidl::Channel) -> Self {
8601 let protocol_name = <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
8602 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
8603 }
8604
8605 pub fn into_channel(self) -> fidl::Channel {
8606 self.client.into_channel()
8607 }
8608
8609 /// Waits until an event arrives and returns it. It is safe for other
8610 /// threads to make concurrent requests while waiting for an event.
8611 pub fn wait_for_event(&self, deadline: zx::MonotonicInstant) -> Result<NodeEvent, fidl::Error> {
8612 NodeEvent::decode(self.client.wait_for_event(deadline)?)
8613 }
8614
8615 /// Ensure that previous messages, including Duplicate() messages on a
8616 /// token, collection, or group, have been received server side.
8617 ///
8618 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
8619 /// valid sysmem token risks the Sync() hanging forever. See
8620 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
8621 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
8622 /// Another way is to pass the token to BindSharedCollection(), which also
8623 /// validates the token as part of exchanging it for a BufferCollection
8624 /// channel, and BufferCollection Sync() can then be used.
8625 ///
8626 /// After a Sync(), it's then safe to send the client end of token_request
8627 /// to another participant knowing the server will recognize the token when
8628 /// it's sent into BindSharedCollection() by the other participant.
8629 ///
8630 /// Other options include waiting for each token.Duplicate() to complete
8631 /// individually (using separate call to token.Sync() after each), or
8632 /// calling Sync() on BufferCollection after the token has been turned in
8633 /// via BindSharedCollection().
8634 ///
8635 /// Another way to mitigate is to avoid calling Sync() on the token, and
8636 /// instead later deal with potential failure of BufferCollection.Sync() if
8637 /// the original token was invalid. This option can be preferable from a
8638 /// performance point of view, but requires client code to delay sending
8639 /// tokens duplicated from this token until after client code has converted
8640 /// the duplicating token to a BufferCollection and received successful
8641 /// response from BufferCollection.Sync().
8642 ///
8643 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
8644 /// When BufferCollection.Sync() isn't feasible, the caller must already
8645 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
8646 /// hang forever. See ValidateBufferCollectionToken() to check token
8647 /// validity first if the token isn't already known to be (is/was) valid.
8648 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
8649 let _response =
8650 self.client.send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload>(
8651 (),
8652 0x4577e238ae26291,
8653 fidl::encoding::DynamicFlags::empty(),
8654 ___deadline,
8655 )?;
8656 Ok(_response)
8657 }
8658
8659 /// On a BufferCollectionToken channel:
8660 ///
8661 /// Normally a participant will convert a BufferCollectionToken into a
8662 /// BufferCollection view, but a participant is also free to Close() the
8663 /// token (and then close the channel immediately or shortly later in
8664 /// response to server closing its end), which avoids causing logical buffer
8665 /// collection failure. Â Normally an unexpected token channel close will
8666 /// cause logical buffer collection failure (the only exceptions being
8667 /// certain cases involving AttachToken() or SetDispensable()).
8668 ///
8669 /// On a BufferCollection channel:
8670 ///
8671 /// By default the server handles unexpected failure of a BufferCollection
8672 /// by failing the whole logical buffer collection. Partly this is to
8673 /// expedite closing VMO handles to reclaim memory when any participant
8674 /// fails. If a participant would like to cleanly close a BufferCollection
8675 /// view without causing logical buffer collection failure, the participant
8676 /// can send Close() before closing the client end of the BufferCollection
8677 /// channel. If this is the last BufferCollection view, the logical buffer
8678 /// collection will still go away. The Close() can occur before or after
8679 /// SetConstraints(). If before SetConstraints(), the buffer collection
8680 /// won't require constraints from this node in order to allocate. If
8681 /// after SetConstraints(), the constraints are retained and aggregated
8682 /// along with any subsequent logical allocation(s), despite the lack of
8683 /// channel connection.
8684 ///
8685 /// On a BufferCollectionTokenGroup channel:
8686 ///
8687 /// By default, unexpected failure of a BufferCollectionTokenGroup will
8688 /// trigger failure of the logical BufferCollectionTokenGroup and will
8689 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
8690 /// channel without failing the logical group or propagating failure, send
8691 /// Close() before closing the channel client endpoint.
8692 ///
8693 /// If Close() occurs before AllChildrenPresent(), the logical buffer
8694 /// collection will still fail despite the Close() (because sysmem can't be
8695 /// sure whether all relevant children were created, so it's ambiguous
8696 /// whether all relevant constraints will be provided to sysmem). If
8697 /// Close() occurs after AllChildrenPresent(), the children and all their
8698 /// constraints remain intact (just as they would if the
8699 /// BufferCollectionTokenGroup channel had remained open), and the close
8700 /// doesn't trigger or propagate failure.
8701 pub fn r#close(&self) -> Result<(), fidl::Error> {
8702 self.client.send::<fidl::encoding::EmptyPayload>(
8703 (),
8704 0x5b1d7a4f5681fca7,
8705 fidl::encoding::DynamicFlags::empty(),
8706 )
8707 }
8708
8709 /// Set a name for VMOs in this buffer collection. The name may be truncated
8710 /// shorter. The name only affects VMOs allocated after it's set - this call
8711 /// does not rename existing VMOs. If multiple clients set different names
8712 /// then the larger priority value will win.
8713 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
8714 self.client.send::<NodeSetNameRequest>(
8715 (priority, name),
8716 0x77a41bb6217e2443,
8717 fidl::encoding::DynamicFlags::empty(),
8718 )
8719 }
8720
8721 /// Set information about the current client that can be used by sysmem to
8722 /// help debug leaking memory and hangs waiting for constraints. |name| can
8723 /// be an arbitrary string, but the current process name (see
8724 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
8725 /// arbitrary id, but the current process ID (see
8726 /// fsl::GetCurrentProcessKoid()) is a good default.
8727 ///
8728 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
8729 /// indicate which client is closing their channel first, leading to
8730 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
8731 /// over, but if happening earlier than expected, the
8732 /// client-channel-specific name can help diagnose where the failure is
8733 /// first coming from, from sysmem's point of view).
8734 ///
8735 /// By default (unless overriden by this message or using
8736 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
8737 /// parent Node at the time the child Node is created. While this can be
8738 /// better than nothing, it's often better for each participant to use
8739 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
8740 /// info directly relevant to the current client. Also, SetVerboseLogging()
8741 /// can be used to help disambiguate if a Node is suspected of having info
8742 /// that was copied from its parent.
8743 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
8744 self.client.send::<NodeSetDebugClientInfoRequest>(
8745 (name, id),
8746 0x7275759070eb5ee2,
8747 fidl::encoding::DynamicFlags::empty(),
8748 )
8749 }
8750
8751 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
8752 /// after creating a collection. Clients can call this method to change
8753 /// when the log is printed. If multiple client set the deadline, it's
8754 /// unspecified which deadline will take effect.
8755 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
8756 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
8757 (deadline,),
8758 0x46d38f4772638867,
8759 fidl::encoding::DynamicFlags::empty(),
8760 )
8761 }
8762
8763 /// Verbose logging includes constraints set via SetConstraints() from each
8764 /// client along with info set via SetDebugClientInfo() and the structure of
8765 /// the tree of Node(s).
8766 ///
8767 /// Normally sysmem prints only a single line complaint when aggregation
8768 /// fails, with just the specific detailed reason that aggregation failed,
8769 /// with minimal context. While this is often enough to diagnose a problem
8770 /// if only a small change was made and the system had been working before
8771 /// the small change, it's often not particularly helpful for getting a new
8772 /// buffer collection to work for the first time. Especially with more
8773 /// complex trees of nodes, involving things like AttachToken(),
8774 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
8775 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
8776 /// looks like and why it's failing a logical allocation, or why a tree or
8777 /// sub-tree is failing sooner than expected.
8778 ///
8779 /// The intent of the extra logging is to be acceptable from a performance
8780 /// point of view, if only enabled on a low number of buffer collections.
8781 /// If we're not tracking down a bug, we shouldn't send this message.
8782 ///
8783 /// If too many participants leave verbose logging enabled, we may end up
8784 /// needing to require that system-wide sysmem verbose logging be permitted
8785 /// via some other setting, to avoid sysmem spamming the log too much due to
8786 /// this message.
8787 ///
8788 /// This may be a NOP for some nodes due to intentional policy associated
8789 /// with the node, if we don't trust a node enough to let it turn on verbose
8790 /// logging.
8791 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
8792 self.client.send::<fidl::encoding::EmptyPayload>(
8793 (),
8794 0x6bfbe2cf1701d288,
8795 fidl::encoding::DynamicFlags::empty(),
8796 )
8797 }
8798
8799 /// This gets an event handle that can be used as a parameter to
8800 /// IsAlternateFor() called on any Node. The client will not be granted the
8801 /// right to signal this event, as this handle should only be used as proof
8802 /// that the client obtained this handle from this Node.
8803 ///
8804 /// Because this is a get not a set, no Sync() is needed between the
8805 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
8806 /// potentially being on different channels.
8807 ///
8808 /// See also IsAlternateFor().
8809 pub fn r#get_node_ref(
8810 &self,
8811 ___deadline: zx::MonotonicInstant,
8812 ) -> Result<fidl::Event, fidl::Error> {
8813 let _response =
8814 self.client.send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse>(
8815 (),
8816 0x467b7c75c35c3b84,
8817 fidl::encoding::DynamicFlags::empty(),
8818 ___deadline,
8819 )?;
8820 Ok(_response.node_ref)
8821 }
8822
8823 /// This checks whether the calling node is in a subtree rooted at a
8824 /// different child token of a common parent BufferCollectionTokenGroup, in
8825 /// relation to the passed-in node_ref.
8826 ///
8827 /// This call is for assisting with admission control de-duplication, and
8828 /// with debugging.
8829 ///
8830 /// The node_ref must be obtained using GetNodeRef() of a
8831 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
8832 ///
8833 /// The node_ref can be a duplicated handle; it's not necessary to call
8834 /// GetNodeRef() for every call to IsAlternateFor().
8835 ///
8836 /// If a calling token may not actually be a valid token at all due to
8837 /// a potentially hostile/untrusted provider of the token, call
8838 /// ValidateBufferCollectionToken() first instead of potentially getting
8839 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
8840 /// token not being a real token (not really talking to sysmem). Another
8841 /// option is to call BindSharedCollection with this token first which also
8842 /// validates the token along with converting it to a BufferCollection, then
8843 /// call BufferCollection IsAlternateFor().
8844 ///
8845 /// error values:
8846 ///
8847 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
8848 /// buffer collection as the calling Node. Before logical allocation and
8849 /// within the same logical allocation sub-tree, this essentially means that
8850 /// the node_ref was never part of this logical buffer collection, since
8851 /// before logical allocation all node_refs that come into existence remain
8852 /// in existence at least until logical allocation (including Node(s) that
8853 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
8854 /// to be returned, this Node's channel needs to still be connected server
8855 /// side, which won't be the case if the whole logical allocation has
8856 /// failed. After logical allocation or in a different logical allocation
8857 /// sub-tree there are additional potential reasons for this error. For
8858 /// example a different logical allocation (separated from this Node(s)
8859 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
8860 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
8861 /// exist and may select a different child sub-tree than the sub-tree the
8862 /// node_ref is in causing deletion of the node_ref Node. The only time
8863 /// sysmem keeps a Node around after that Node has no corresponding channel
8864 /// is when Close() is used and the Node's sub-tree has not yet failed.
8865 /// Another reason for this error is if the node_ref is an eventpair handle
8866 /// with sufficient rights, but isn't actually a real node_ref obtained from
8867 /// GetNodeRef().
8868 ///
8869 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
8870 /// eventpair handle, or doesn't have the needed rights expected on a real
8871 /// node_ref.
8872 ///
8873 /// No other failing status codes are returned by this call. However,
8874 /// sysmem may add additional codes in future, so the client should have
8875 /// sensible default handling for any failing status code.
8876 ///
8877 /// On success, is_alternate has the following meaning:
8878 /// * true - The first parent node in common between the calling node and
8879 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
8880 /// the calling Node and the node_ref Node will _not_ have both their
8881 /// constraints apply - rather sysmem will choose one or the other of
8882 /// the constraints - never both. This is because only one child of
8883 /// a BufferCollectionTokenGroup is selected during logical allocation,
8884 /// with only that one child's sub-tree contributing to constraints
8885 /// aggregation.
8886 /// * false - The first parent node in common between the calling Node and
8887 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
8888 /// this means the first parent node in common is a
8889 /// BufferCollectionToken or BufferCollection (regardless of not
8890 /// Close()ed or Close()ed). This means that the calling Node and the
8891 /// node_ref Node _may_ have both their constraints apply during
8892 /// constraints aggregation of the logical allocation, if both Node(s)
8893 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
8894 /// In this case, there is no BufferCollectionTokenGroup that will
8895 /// directly prevent the two Node(s) from both being selected and their
8896 /// constraints both aggregated, but even when false, one or both
8897 /// Node(s) may still be eliminated from consideration if one or both
8898 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
8899 /// which selects a child sub-tree other than the sub-tree containing
8900 /// the calling Node or node_ref Node.
8901 pub fn r#is_alternate_for(
8902 &self,
8903 mut node_ref: fidl::Event,
8904 ___deadline: zx::MonotonicInstant,
8905 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
8906 let _response = self.client.send_query::<
8907 NodeIsAlternateForRequest,
8908 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
8909 >(
8910 (node_ref,),
8911 0x33a2a7aff2776c07,
8912 fidl::encoding::DynamicFlags::empty(),
8913 ___deadline,
8914 )?;
8915 Ok(_response.map(|x| x.is_alternate))
8916 }
8917}
8918
8919#[cfg(target_os = "fuchsia")]
8920impl From<NodeSynchronousProxy> for zx::NullableHandle {
8921 fn from(value: NodeSynchronousProxy) -> Self {
8922 value.into_channel().into()
8923 }
8924}
8925
8926#[cfg(target_os = "fuchsia")]
8927impl From<fidl::Channel> for NodeSynchronousProxy {
8928 fn from(value: fidl::Channel) -> Self {
8929 Self::new(value)
8930 }
8931}
8932
8933#[cfg(target_os = "fuchsia")]
8934impl fidl::endpoints::FromClient for NodeSynchronousProxy {
8935 type Protocol = NodeMarker;
8936
8937 fn from_client(value: fidl::endpoints::ClientEnd<NodeMarker>) -> Self {
8938 Self::new(value.into_channel())
8939 }
8940}
8941
8942#[derive(Debug, Clone)]
8943pub struct NodeProxy {
8944 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
8945}
8946
8947impl fidl::endpoints::Proxy for NodeProxy {
8948 type Protocol = NodeMarker;
8949
8950 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
8951 Self::new(inner)
8952 }
8953
8954 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
8955 self.client.into_channel().map_err(|client| Self { client })
8956 }
8957
8958 fn as_channel(&self) -> &::fidl::AsyncChannel {
8959 self.client.as_channel()
8960 }
8961}
8962
8963impl NodeProxy {
8964 /// Create a new Proxy for fuchsia.sysmem/Node.
8965 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
8966 let protocol_name = <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
8967 Self { client: fidl::client::Client::new(channel, protocol_name) }
8968 }
8969
8970 /// Get a Stream of events from the remote end of the protocol.
8971 ///
8972 /// # Panics
8973 ///
8974 /// Panics if the event stream was already taken.
8975 pub fn take_event_stream(&self) -> NodeEventStream {
8976 NodeEventStream { event_receiver: self.client.take_event_receiver() }
8977 }
8978
8979 /// Ensure that previous messages, including Duplicate() messages on a
8980 /// token, collection, or group, have been received server side.
8981 ///
8982 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
8983 /// valid sysmem token risks the Sync() hanging forever. See
8984 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
8985 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
8986 /// Another way is to pass the token to BindSharedCollection(), which also
8987 /// validates the token as part of exchanging it for a BufferCollection
8988 /// channel, and BufferCollection Sync() can then be used.
8989 ///
8990 /// After a Sync(), it's then safe to send the client end of token_request
8991 /// to another participant knowing the server will recognize the token when
8992 /// it's sent into BindSharedCollection() by the other participant.
8993 ///
8994 /// Other options include waiting for each token.Duplicate() to complete
8995 /// individually (using separate call to token.Sync() after each), or
8996 /// calling Sync() on BufferCollection after the token has been turned in
8997 /// via BindSharedCollection().
8998 ///
8999 /// Another way to mitigate is to avoid calling Sync() on the token, and
9000 /// instead later deal with potential failure of BufferCollection.Sync() if
9001 /// the original token was invalid. This option can be preferable from a
9002 /// performance point of view, but requires client code to delay sending
9003 /// tokens duplicated from this token until after client code has converted
9004 /// the duplicating token to a BufferCollection and received successful
9005 /// response from BufferCollection.Sync().
9006 ///
9007 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
9008 /// When BufferCollection.Sync() isn't feasible, the caller must already
9009 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
9010 /// hang forever. See ValidateBufferCollectionToken() to check token
9011 /// validity first if the token isn't already known to be (is/was) valid.
9012 pub fn r#sync(
9013 &self,
9014 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
9015 NodeProxyInterface::r#sync(self)
9016 }
9017
9018 /// On a BufferCollectionToken channel:
9019 ///
9020 /// Normally a participant will convert a BufferCollectionToken into a
9021 /// BufferCollection view, but a participant is also free to Close() the
9022 /// token (and then close the channel immediately or shortly later in
9023 /// response to server closing its end), which avoids causing logical buffer
9024 /// collection failure. Â Normally an unexpected token channel close will
9025 /// cause logical buffer collection failure (the only exceptions being
9026 /// certain cases involving AttachToken() or SetDispensable()).
9027 ///
9028 /// On a BufferCollection channel:
9029 ///
9030 /// By default the server handles unexpected failure of a BufferCollection
9031 /// by failing the whole logical buffer collection. Partly this is to
9032 /// expedite closing VMO handles to reclaim memory when any participant
9033 /// fails. If a participant would like to cleanly close a BufferCollection
9034 /// view without causing logical buffer collection failure, the participant
9035 /// can send Close() before closing the client end of the BufferCollection
9036 /// channel. If this is the last BufferCollection view, the logical buffer
9037 /// collection will still go away. The Close() can occur before or after
9038 /// SetConstraints(). If before SetConstraints(), the buffer collection
9039 /// won't require constraints from this node in order to allocate. If
9040 /// after SetConstraints(), the constraints are retained and aggregated
9041 /// along with any subsequent logical allocation(s), despite the lack of
9042 /// channel connection.
9043 ///
9044 /// On a BufferCollectionTokenGroup channel:
9045 ///
9046 /// By default, unexpected failure of a BufferCollectionTokenGroup will
9047 /// trigger failure of the logical BufferCollectionTokenGroup and will
9048 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
9049 /// channel without failing the logical group or propagating failure, send
9050 /// Close() before closing the channel client endpoint.
9051 ///
9052 /// If Close() occurs before AllChildrenPresent(), the logical buffer
9053 /// collection will still fail despite the Close() (because sysmem can't be
9054 /// sure whether all relevant children were created, so it's ambiguous
9055 /// whether all relevant constraints will be provided to sysmem). If
9056 /// Close() occurs after AllChildrenPresent(), the children and all their
9057 /// constraints remain intact (just as they would if the
9058 /// BufferCollectionTokenGroup channel had remained open), and the close
9059 /// doesn't trigger or propagate failure.
9060 pub fn r#close(&self) -> Result<(), fidl::Error> {
9061 NodeProxyInterface::r#close(self)
9062 }
9063
9064 /// Set a name for VMOs in this buffer collection. The name may be truncated
9065 /// shorter. The name only affects VMOs allocated after it's set - this call
9066 /// does not rename existing VMOs. If multiple clients set different names
9067 /// then the larger priority value will win.
9068 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
9069 NodeProxyInterface::r#set_name(self, priority, name)
9070 }
9071
9072 /// Set information about the current client that can be used by sysmem to
9073 /// help debug leaking memory and hangs waiting for constraints. |name| can
9074 /// be an arbitrary string, but the current process name (see
9075 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
9076 /// arbitrary id, but the current process ID (see
9077 /// fsl::GetCurrentProcessKoid()) is a good default.
9078 ///
9079 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
9080 /// indicate which client is closing their channel first, leading to
9081 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
9082 /// over, but if happening earlier than expected, the
9083 /// client-channel-specific name can help diagnose where the failure is
9084 /// first coming from, from sysmem's point of view).
9085 ///
9086 /// By default (unless overriden by this message or using
9087 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
9088 /// parent Node at the time the child Node is created. While this can be
9089 /// better than nothing, it's often better for each participant to use
9090 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
9091 /// info directly relevant to the current client. Also, SetVerboseLogging()
9092 /// can be used to help disambiguate if a Node is suspected of having info
9093 /// that was copied from its parent.
9094 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
9095 NodeProxyInterface::r#set_debug_client_info(self, name, id)
9096 }
9097
9098 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
9099 /// after creating a collection. Clients can call this method to change
9100 /// when the log is printed. If multiple client set the deadline, it's
9101 /// unspecified which deadline will take effect.
9102 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
9103 NodeProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
9104 }
9105
9106 /// Verbose logging includes constraints set via SetConstraints() from each
9107 /// client along with info set via SetDebugClientInfo() and the structure of
9108 /// the tree of Node(s).
9109 ///
9110 /// Normally sysmem prints only a single line complaint when aggregation
9111 /// fails, with just the specific detailed reason that aggregation failed,
9112 /// with minimal context. While this is often enough to diagnose a problem
9113 /// if only a small change was made and the system had been working before
9114 /// the small change, it's often not particularly helpful for getting a new
9115 /// buffer collection to work for the first time. Especially with more
9116 /// complex trees of nodes, involving things like AttachToken(),
9117 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
9118 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
9119 /// looks like and why it's failing a logical allocation, or why a tree or
9120 /// sub-tree is failing sooner than expected.
9121 ///
9122 /// The intent of the extra logging is to be acceptable from a performance
9123 /// point of view, if only enabled on a low number of buffer collections.
9124 /// If we're not tracking down a bug, we shouldn't send this message.
9125 ///
9126 /// If too many participants leave verbose logging enabled, we may end up
9127 /// needing to require that system-wide sysmem verbose logging be permitted
9128 /// via some other setting, to avoid sysmem spamming the log too much due to
9129 /// this message.
9130 ///
9131 /// This may be a NOP for some nodes due to intentional policy associated
9132 /// with the node, if we don't trust a node enough to let it turn on verbose
9133 /// logging.
9134 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
9135 NodeProxyInterface::r#set_verbose_logging(self)
9136 }
9137
9138 /// This gets an event handle that can be used as a parameter to
9139 /// IsAlternateFor() called on any Node. The client will not be granted the
9140 /// right to signal this event, as this handle should only be used as proof
9141 /// that the client obtained this handle from this Node.
9142 ///
9143 /// Because this is a get not a set, no Sync() is needed between the
9144 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
9145 /// potentially being on different channels.
9146 ///
9147 /// See also IsAlternateFor().
9148 pub fn r#get_node_ref(
9149 &self,
9150 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
9151 {
9152 NodeProxyInterface::r#get_node_ref(self)
9153 }
9154
9155 /// This checks whether the calling node is in a subtree rooted at a
9156 /// different child token of a common parent BufferCollectionTokenGroup, in
9157 /// relation to the passed-in node_ref.
9158 ///
9159 /// This call is for assisting with admission control de-duplication, and
9160 /// with debugging.
9161 ///
9162 /// The node_ref must be obtained using GetNodeRef() of a
9163 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
9164 ///
9165 /// The node_ref can be a duplicated handle; it's not necessary to call
9166 /// GetNodeRef() for every call to IsAlternateFor().
9167 ///
9168 /// If a calling token may not actually be a valid token at all due to
9169 /// a potentially hostile/untrusted provider of the token, call
9170 /// ValidateBufferCollectionToken() first instead of potentially getting
9171 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
9172 /// token not being a real token (not really talking to sysmem). Another
9173 /// option is to call BindSharedCollection with this token first which also
9174 /// validates the token along with converting it to a BufferCollection, then
9175 /// call BufferCollection IsAlternateFor().
9176 ///
9177 /// error values:
9178 ///
9179 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
9180 /// buffer collection as the calling Node. Before logical allocation and
9181 /// within the same logical allocation sub-tree, this essentially means that
9182 /// the node_ref was never part of this logical buffer collection, since
9183 /// before logical allocation all node_refs that come into existence remain
9184 /// in existence at least until logical allocation (including Node(s) that
9185 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
9186 /// to be returned, this Node's channel needs to still be connected server
9187 /// side, which won't be the case if the whole logical allocation has
9188 /// failed. After logical allocation or in a different logical allocation
9189 /// sub-tree there are additional potential reasons for this error. For
9190 /// example a different logical allocation (separated from this Node(s)
9191 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
9192 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
9193 /// exist and may select a different child sub-tree than the sub-tree the
9194 /// node_ref is in causing deletion of the node_ref Node. The only time
9195 /// sysmem keeps a Node around after that Node has no corresponding channel
9196 /// is when Close() is used and the Node's sub-tree has not yet failed.
9197 /// Another reason for this error is if the node_ref is an eventpair handle
9198 /// with sufficient rights, but isn't actually a real node_ref obtained from
9199 /// GetNodeRef().
9200 ///
9201 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
9202 /// eventpair handle, or doesn't have the needed rights expected on a real
9203 /// node_ref.
9204 ///
9205 /// No other failing status codes are returned by this call. However,
9206 /// sysmem may add additional codes in future, so the client should have
9207 /// sensible default handling for any failing status code.
9208 ///
9209 /// On success, is_alternate has the following meaning:
9210 /// * true - The first parent node in common between the calling node and
9211 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
9212 /// the calling Node and the node_ref Node will _not_ have both their
9213 /// constraints apply - rather sysmem will choose one or the other of
9214 /// the constraints - never both. This is because only one child of
9215 /// a BufferCollectionTokenGroup is selected during logical allocation,
9216 /// with only that one child's sub-tree contributing to constraints
9217 /// aggregation.
9218 /// * false - The first parent node in common between the calling Node and
9219 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
9220 /// this means the first parent node in common is a
9221 /// BufferCollectionToken or BufferCollection (regardless of not
9222 /// Close()ed or Close()ed). This means that the calling Node and the
9223 /// node_ref Node _may_ have both their constraints apply during
9224 /// constraints aggregation of the logical allocation, if both Node(s)
9225 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
9226 /// In this case, there is no BufferCollectionTokenGroup that will
9227 /// directly prevent the two Node(s) from both being selected and their
9228 /// constraints both aggregated, but even when false, one or both
9229 /// Node(s) may still be eliminated from consideration if one or both
9230 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
9231 /// which selects a child sub-tree other than the sub-tree containing
9232 /// the calling Node or node_ref Node.
9233 pub fn r#is_alternate_for(
9234 &self,
9235 mut node_ref: fidl::Event,
9236 ) -> fidl::client::QueryResponseFut<
9237 NodeIsAlternateForResult,
9238 fidl::encoding::DefaultFuchsiaResourceDialect,
9239 > {
9240 NodeProxyInterface::r#is_alternate_for(self, node_ref)
9241 }
9242}
9243
9244impl NodeProxyInterface for NodeProxy {
9245 type SyncResponseFut =
9246 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
9247 fn r#sync(&self) -> Self::SyncResponseFut {
9248 fn _decode(
9249 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9250 ) -> Result<(), fidl::Error> {
9251 let _response = fidl::client::decode_transaction_body::<
9252 fidl::encoding::EmptyPayload,
9253 fidl::encoding::DefaultFuchsiaResourceDialect,
9254 0x4577e238ae26291,
9255 >(_buf?)?;
9256 Ok(_response)
9257 }
9258 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
9259 (),
9260 0x4577e238ae26291,
9261 fidl::encoding::DynamicFlags::empty(),
9262 _decode,
9263 )
9264 }
9265
9266 fn r#close(&self) -> Result<(), fidl::Error> {
9267 self.client.send::<fidl::encoding::EmptyPayload>(
9268 (),
9269 0x5b1d7a4f5681fca7,
9270 fidl::encoding::DynamicFlags::empty(),
9271 )
9272 }
9273
9274 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
9275 self.client.send::<NodeSetNameRequest>(
9276 (priority, name),
9277 0x77a41bb6217e2443,
9278 fidl::encoding::DynamicFlags::empty(),
9279 )
9280 }
9281
9282 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
9283 self.client.send::<NodeSetDebugClientInfoRequest>(
9284 (name, id),
9285 0x7275759070eb5ee2,
9286 fidl::encoding::DynamicFlags::empty(),
9287 )
9288 }
9289
9290 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
9291 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
9292 (deadline,),
9293 0x46d38f4772638867,
9294 fidl::encoding::DynamicFlags::empty(),
9295 )
9296 }
9297
9298 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
9299 self.client.send::<fidl::encoding::EmptyPayload>(
9300 (),
9301 0x6bfbe2cf1701d288,
9302 fidl::encoding::DynamicFlags::empty(),
9303 )
9304 }
9305
9306 type GetNodeRefResponseFut =
9307 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
9308 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
9309 fn _decode(
9310 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9311 ) -> Result<fidl::Event, fidl::Error> {
9312 let _response = fidl::client::decode_transaction_body::<
9313 NodeGetNodeRefResponse,
9314 fidl::encoding::DefaultFuchsiaResourceDialect,
9315 0x467b7c75c35c3b84,
9316 >(_buf?)?;
9317 Ok(_response.node_ref)
9318 }
9319 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
9320 (),
9321 0x467b7c75c35c3b84,
9322 fidl::encoding::DynamicFlags::empty(),
9323 _decode,
9324 )
9325 }
9326
9327 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
9328 NodeIsAlternateForResult,
9329 fidl::encoding::DefaultFuchsiaResourceDialect,
9330 >;
9331 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
9332 fn _decode(
9333 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9334 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
9335 let _response = fidl::client::decode_transaction_body::<
9336 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
9337 fidl::encoding::DefaultFuchsiaResourceDialect,
9338 0x33a2a7aff2776c07,
9339 >(_buf?)?;
9340 Ok(_response.map(|x| x.is_alternate))
9341 }
9342 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
9343 (node_ref,),
9344 0x33a2a7aff2776c07,
9345 fidl::encoding::DynamicFlags::empty(),
9346 _decode,
9347 )
9348 }
9349}
9350
9351pub struct NodeEventStream {
9352 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
9353}
9354
9355impl std::marker::Unpin for NodeEventStream {}
9356
9357impl futures::stream::FusedStream for NodeEventStream {
9358 fn is_terminated(&self) -> bool {
9359 self.event_receiver.is_terminated()
9360 }
9361}
9362
9363impl futures::Stream for NodeEventStream {
9364 type Item = Result<NodeEvent, fidl::Error>;
9365
9366 fn poll_next(
9367 mut self: std::pin::Pin<&mut Self>,
9368 cx: &mut std::task::Context<'_>,
9369 ) -> std::task::Poll<Option<Self::Item>> {
9370 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
9371 &mut self.event_receiver,
9372 cx
9373 )?) {
9374 Some(buf) => std::task::Poll::Ready(Some(NodeEvent::decode(buf))),
9375 None => std::task::Poll::Ready(None),
9376 }
9377 }
9378}
9379
9380#[derive(Debug)]
9381pub enum NodeEvent {}
9382
9383impl NodeEvent {
9384 /// Decodes a message buffer as a [`NodeEvent`].
9385 fn decode(
9386 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
9387 ) -> Result<NodeEvent, fidl::Error> {
9388 let (bytes, _handles) = buf.split_mut();
9389 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
9390 debug_assert_eq!(tx_header.tx_id, 0);
9391 match tx_header.ordinal {
9392 _ => Err(fidl::Error::UnknownOrdinal {
9393 ordinal: tx_header.ordinal,
9394 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
9395 }),
9396 }
9397 }
9398}
9399
9400/// A Stream of incoming requests for fuchsia.sysmem/Node.
9401pub struct NodeRequestStream {
9402 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9403 is_terminated: bool,
9404}
9405
9406impl std::marker::Unpin for NodeRequestStream {}
9407
9408impl futures::stream::FusedStream for NodeRequestStream {
9409 fn is_terminated(&self) -> bool {
9410 self.is_terminated
9411 }
9412}
9413
9414impl fidl::endpoints::RequestStream for NodeRequestStream {
9415 type Protocol = NodeMarker;
9416 type ControlHandle = NodeControlHandle;
9417
9418 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
9419 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
9420 }
9421
9422 fn control_handle(&self) -> Self::ControlHandle {
9423 NodeControlHandle { inner: self.inner.clone() }
9424 }
9425
9426 fn into_inner(
9427 self,
9428 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
9429 {
9430 (self.inner, self.is_terminated)
9431 }
9432
9433 fn from_inner(
9434 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9435 is_terminated: bool,
9436 ) -> Self {
9437 Self { inner, is_terminated }
9438 }
9439}
9440
9441impl futures::Stream for NodeRequestStream {
9442 type Item = Result<NodeRequest, fidl::Error>;
9443
9444 fn poll_next(
9445 mut self: std::pin::Pin<&mut Self>,
9446 cx: &mut std::task::Context<'_>,
9447 ) -> std::task::Poll<Option<Self::Item>> {
9448 let this = &mut *self;
9449 if this.inner.check_shutdown(cx) {
9450 this.is_terminated = true;
9451 return std::task::Poll::Ready(None);
9452 }
9453 if this.is_terminated {
9454 panic!("polled NodeRequestStream after completion");
9455 }
9456 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
9457 |bytes, handles| {
9458 match this.inner.channel().read_etc(cx, bytes, handles) {
9459 std::task::Poll::Ready(Ok(())) => {}
9460 std::task::Poll::Pending => return std::task::Poll::Pending,
9461 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
9462 this.is_terminated = true;
9463 return std::task::Poll::Ready(None);
9464 }
9465 std::task::Poll::Ready(Err(e)) => {
9466 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
9467 e.into(),
9468 ))));
9469 }
9470 }
9471
9472 // A message has been received from the channel
9473 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
9474
9475 std::task::Poll::Ready(Some(match header.ordinal {
9476 0x4577e238ae26291 => {
9477 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9478 let mut req = fidl::new_empty!(
9479 fidl::encoding::EmptyPayload,
9480 fidl::encoding::DefaultFuchsiaResourceDialect
9481 );
9482 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9483 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9484 Ok(NodeRequest::Sync {
9485 responder: NodeSyncResponder {
9486 control_handle: std::mem::ManuallyDrop::new(control_handle),
9487 tx_id: header.tx_id,
9488 },
9489 })
9490 }
9491 0x5b1d7a4f5681fca7 => {
9492 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9493 let mut req = fidl::new_empty!(
9494 fidl::encoding::EmptyPayload,
9495 fidl::encoding::DefaultFuchsiaResourceDialect
9496 );
9497 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9498 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9499 Ok(NodeRequest::Close { control_handle })
9500 }
9501 0x77a41bb6217e2443 => {
9502 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9503 let mut req = fidl::new_empty!(
9504 NodeSetNameRequest,
9505 fidl::encoding::DefaultFuchsiaResourceDialect
9506 );
9507 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
9508 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9509 Ok(NodeRequest::SetName {
9510 priority: req.priority,
9511 name: req.name,
9512
9513 control_handle,
9514 })
9515 }
9516 0x7275759070eb5ee2 => {
9517 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9518 let mut req = fidl::new_empty!(
9519 NodeSetDebugClientInfoRequest,
9520 fidl::encoding::DefaultFuchsiaResourceDialect
9521 );
9522 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
9523 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9524 Ok(NodeRequest::SetDebugClientInfo {
9525 name: req.name,
9526 id: req.id,
9527
9528 control_handle,
9529 })
9530 }
9531 0x46d38f4772638867 => {
9532 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9533 let mut req = fidl::new_empty!(
9534 NodeSetDebugTimeoutLogDeadlineRequest,
9535 fidl::encoding::DefaultFuchsiaResourceDialect
9536 );
9537 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
9538 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9539 Ok(NodeRequest::SetDebugTimeoutLogDeadline {
9540 deadline: req.deadline,
9541
9542 control_handle,
9543 })
9544 }
9545 0x6bfbe2cf1701d288 => {
9546 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9547 let mut req = fidl::new_empty!(
9548 fidl::encoding::EmptyPayload,
9549 fidl::encoding::DefaultFuchsiaResourceDialect
9550 );
9551 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9552 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9553 Ok(NodeRequest::SetVerboseLogging { control_handle })
9554 }
9555 0x467b7c75c35c3b84 => {
9556 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9557 let mut req = fidl::new_empty!(
9558 fidl::encoding::EmptyPayload,
9559 fidl::encoding::DefaultFuchsiaResourceDialect
9560 );
9561 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9562 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9563 Ok(NodeRequest::GetNodeRef {
9564 responder: NodeGetNodeRefResponder {
9565 control_handle: std::mem::ManuallyDrop::new(control_handle),
9566 tx_id: header.tx_id,
9567 },
9568 })
9569 }
9570 0x33a2a7aff2776c07 => {
9571 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9572 let mut req = fidl::new_empty!(
9573 NodeIsAlternateForRequest,
9574 fidl::encoding::DefaultFuchsiaResourceDialect
9575 );
9576 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
9577 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9578 Ok(NodeRequest::IsAlternateFor {
9579 node_ref: req.node_ref,
9580
9581 responder: NodeIsAlternateForResponder {
9582 control_handle: std::mem::ManuallyDrop::new(control_handle),
9583 tx_id: header.tx_id,
9584 },
9585 })
9586 }
9587 _ => Err(fidl::Error::UnknownOrdinal {
9588 ordinal: header.ordinal,
9589 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
9590 }),
9591 }))
9592 },
9593 )
9594 }
9595}
9596
9597#[derive(Debug)]
9598pub enum NodeRequest {
9599 /// Ensure that previous messages, including Duplicate() messages on a
9600 /// token, collection, or group, have been received server side.
9601 ///
9602 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
9603 /// valid sysmem token risks the Sync() hanging forever. See
9604 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
9605 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
9606 /// Another way is to pass the token to BindSharedCollection(), which also
9607 /// validates the token as part of exchanging it for a BufferCollection
9608 /// channel, and BufferCollection Sync() can then be used.
9609 ///
9610 /// After a Sync(), it's then safe to send the client end of token_request
9611 /// to another participant knowing the server will recognize the token when
9612 /// it's sent into BindSharedCollection() by the other participant.
9613 ///
9614 /// Other options include waiting for each token.Duplicate() to complete
9615 /// individually (using separate call to token.Sync() after each), or
9616 /// calling Sync() on BufferCollection after the token has been turned in
9617 /// via BindSharedCollection().
9618 ///
9619 /// Another way to mitigate is to avoid calling Sync() on the token, and
9620 /// instead later deal with potential failure of BufferCollection.Sync() if
9621 /// the original token was invalid. This option can be preferable from a
9622 /// performance point of view, but requires client code to delay sending
9623 /// tokens duplicated from this token until after client code has converted
9624 /// the duplicating token to a BufferCollection and received successful
9625 /// response from BufferCollection.Sync().
9626 ///
9627 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
9628 /// When BufferCollection.Sync() isn't feasible, the caller must already
9629 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
9630 /// hang forever. See ValidateBufferCollectionToken() to check token
9631 /// validity first if the token isn't already known to be (is/was) valid.
9632 Sync { responder: NodeSyncResponder },
9633 /// On a BufferCollectionToken channel:
9634 ///
9635 /// Normally a participant will convert a BufferCollectionToken into a
9636 /// BufferCollection view, but a participant is also free to Close() the
9637 /// token (and then close the channel immediately or shortly later in
9638 /// response to server closing its end), which avoids causing logical buffer
9639 /// collection failure. Â Normally an unexpected token channel close will
9640 /// cause logical buffer collection failure (the only exceptions being
9641 /// certain cases involving AttachToken() or SetDispensable()).
9642 ///
9643 /// On a BufferCollection channel:
9644 ///
9645 /// By default the server handles unexpected failure of a BufferCollection
9646 /// by failing the whole logical buffer collection. Partly this is to
9647 /// expedite closing VMO handles to reclaim memory when any participant
9648 /// fails. If a participant would like to cleanly close a BufferCollection
9649 /// view without causing logical buffer collection failure, the participant
9650 /// can send Close() before closing the client end of the BufferCollection
9651 /// channel. If this is the last BufferCollection view, the logical buffer
9652 /// collection will still go away. The Close() can occur before or after
9653 /// SetConstraints(). If before SetConstraints(), the buffer collection
9654 /// won't require constraints from this node in order to allocate. If
9655 /// after SetConstraints(), the constraints are retained and aggregated
9656 /// along with any subsequent logical allocation(s), despite the lack of
9657 /// channel connection.
9658 ///
9659 /// On a BufferCollectionTokenGroup channel:
9660 ///
9661 /// By default, unexpected failure of a BufferCollectionTokenGroup will
9662 /// trigger failure of the logical BufferCollectionTokenGroup and will
9663 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
9664 /// channel without failing the logical group or propagating failure, send
9665 /// Close() before closing the channel client endpoint.
9666 ///
9667 /// If Close() occurs before AllChildrenPresent(), the logical buffer
9668 /// collection will still fail despite the Close() (because sysmem can't be
9669 /// sure whether all relevant children were created, so it's ambiguous
9670 /// whether all relevant constraints will be provided to sysmem). If
9671 /// Close() occurs after AllChildrenPresent(), the children and all their
9672 /// constraints remain intact (just as they would if the
9673 /// BufferCollectionTokenGroup channel had remained open), and the close
9674 /// doesn't trigger or propagate failure.
9675 Close { control_handle: NodeControlHandle },
9676 /// Set a name for VMOs in this buffer collection. The name may be truncated
9677 /// shorter. The name only affects VMOs allocated after it's set - this call
9678 /// does not rename existing VMOs. If multiple clients set different names
9679 /// then the larger priority value will win.
9680 SetName { priority: u32, name: String, control_handle: NodeControlHandle },
9681 /// Set information about the current client that can be used by sysmem to
9682 /// help debug leaking memory and hangs waiting for constraints. |name| can
9683 /// be an arbitrary string, but the current process name (see
9684 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
9685 /// arbitrary id, but the current process ID (see
9686 /// fsl::GetCurrentProcessKoid()) is a good default.
9687 ///
9688 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
9689 /// indicate which client is closing their channel first, leading to
9690 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
9691 /// over, but if happening earlier than expected, the
9692 /// client-channel-specific name can help diagnose where the failure is
9693 /// first coming from, from sysmem's point of view).
9694 ///
9695 /// By default (unless overriden by this message or using
9696 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
9697 /// parent Node at the time the child Node is created. While this can be
9698 /// better than nothing, it's often better for each participant to use
9699 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
9700 /// info directly relevant to the current client. Also, SetVerboseLogging()
9701 /// can be used to help disambiguate if a Node is suspected of having info
9702 /// that was copied from its parent.
9703 SetDebugClientInfo { name: String, id: u64, control_handle: NodeControlHandle },
9704 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
9705 /// after creating a collection. Clients can call this method to change
9706 /// when the log is printed. If multiple client set the deadline, it's
9707 /// unspecified which deadline will take effect.
9708 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: NodeControlHandle },
9709 /// Verbose logging includes constraints set via SetConstraints() from each
9710 /// client along with info set via SetDebugClientInfo() and the structure of
9711 /// the tree of Node(s).
9712 ///
9713 /// Normally sysmem prints only a single line complaint when aggregation
9714 /// fails, with just the specific detailed reason that aggregation failed,
9715 /// with minimal context. While this is often enough to diagnose a problem
9716 /// if only a small change was made and the system had been working before
9717 /// the small change, it's often not particularly helpful for getting a new
9718 /// buffer collection to work for the first time. Especially with more
9719 /// complex trees of nodes, involving things like AttachToken(),
9720 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
9721 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
9722 /// looks like and why it's failing a logical allocation, or why a tree or
9723 /// sub-tree is failing sooner than expected.
9724 ///
9725 /// The intent of the extra logging is to be acceptable from a performance
9726 /// point of view, if only enabled on a low number of buffer collections.
9727 /// If we're not tracking down a bug, we shouldn't send this message.
9728 ///
9729 /// If too many participants leave verbose logging enabled, we may end up
9730 /// needing to require that system-wide sysmem verbose logging be permitted
9731 /// via some other setting, to avoid sysmem spamming the log too much due to
9732 /// this message.
9733 ///
9734 /// This may be a NOP for some nodes due to intentional policy associated
9735 /// with the node, if we don't trust a node enough to let it turn on verbose
9736 /// logging.
9737 SetVerboseLogging { control_handle: NodeControlHandle },
9738 /// This gets an event handle that can be used as a parameter to
9739 /// IsAlternateFor() called on any Node. The client will not be granted the
9740 /// right to signal this event, as this handle should only be used as proof
9741 /// that the client obtained this handle from this Node.
9742 ///
9743 /// Because this is a get not a set, no Sync() is needed between the
9744 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
9745 /// potentially being on different channels.
9746 ///
9747 /// See also IsAlternateFor().
9748 GetNodeRef { responder: NodeGetNodeRefResponder },
9749 /// This checks whether the calling node is in a subtree rooted at a
9750 /// different child token of a common parent BufferCollectionTokenGroup, in
9751 /// relation to the passed-in node_ref.
9752 ///
9753 /// This call is for assisting with admission control de-duplication, and
9754 /// with debugging.
9755 ///
9756 /// The node_ref must be obtained using GetNodeRef() of a
9757 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
9758 ///
9759 /// The node_ref can be a duplicated handle; it's not necessary to call
9760 /// GetNodeRef() for every call to IsAlternateFor().
9761 ///
9762 /// If a calling token may not actually be a valid token at all due to
9763 /// a potentially hostile/untrusted provider of the token, call
9764 /// ValidateBufferCollectionToken() first instead of potentially getting
9765 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
9766 /// token not being a real token (not really talking to sysmem). Another
9767 /// option is to call BindSharedCollection with this token first which also
9768 /// validates the token along with converting it to a BufferCollection, then
9769 /// call BufferCollection IsAlternateFor().
9770 ///
9771 /// error values:
9772 ///
9773 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
9774 /// buffer collection as the calling Node. Before logical allocation and
9775 /// within the same logical allocation sub-tree, this essentially means that
9776 /// the node_ref was never part of this logical buffer collection, since
9777 /// before logical allocation all node_refs that come into existence remain
9778 /// in existence at least until logical allocation (including Node(s) that
9779 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
9780 /// to be returned, this Node's channel needs to still be connected server
9781 /// side, which won't be the case if the whole logical allocation has
9782 /// failed. After logical allocation or in a different logical allocation
9783 /// sub-tree there are additional potential reasons for this error. For
9784 /// example a different logical allocation (separated from this Node(s)
9785 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
9786 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
9787 /// exist and may select a different child sub-tree than the sub-tree the
9788 /// node_ref is in causing deletion of the node_ref Node. The only time
9789 /// sysmem keeps a Node around after that Node has no corresponding channel
9790 /// is when Close() is used and the Node's sub-tree has not yet failed.
9791 /// Another reason for this error is if the node_ref is an eventpair handle
9792 /// with sufficient rights, but isn't actually a real node_ref obtained from
9793 /// GetNodeRef().
9794 ///
9795 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
9796 /// eventpair handle, or doesn't have the needed rights expected on a real
9797 /// node_ref.
9798 ///
9799 /// No other failing status codes are returned by this call. However,
9800 /// sysmem may add additional codes in future, so the client should have
9801 /// sensible default handling for any failing status code.
9802 ///
9803 /// On success, is_alternate has the following meaning:
9804 /// * true - The first parent node in common between the calling node and
9805 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
9806 /// the calling Node and the node_ref Node will _not_ have both their
9807 /// constraints apply - rather sysmem will choose one or the other of
9808 /// the constraints - never both. This is because only one child of
9809 /// a BufferCollectionTokenGroup is selected during logical allocation,
9810 /// with only that one child's sub-tree contributing to constraints
9811 /// aggregation.
9812 /// * false - The first parent node in common between the calling Node and
9813 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
9814 /// this means the first parent node in common is a
9815 /// BufferCollectionToken or BufferCollection (regardless of not
9816 /// Close()ed or Close()ed). This means that the calling Node and the
9817 /// node_ref Node _may_ have both their constraints apply during
9818 /// constraints aggregation of the logical allocation, if both Node(s)
9819 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
9820 /// In this case, there is no BufferCollectionTokenGroup that will
9821 /// directly prevent the two Node(s) from both being selected and their
9822 /// constraints both aggregated, but even when false, one or both
9823 /// Node(s) may still be eliminated from consideration if one or both
9824 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
9825 /// which selects a child sub-tree other than the sub-tree containing
9826 /// the calling Node or node_ref Node.
9827 IsAlternateFor { node_ref: fidl::Event, responder: NodeIsAlternateForResponder },
9828}
9829
9830impl NodeRequest {
9831 #[allow(irrefutable_let_patterns)]
9832 pub fn into_sync(self) -> Option<(NodeSyncResponder)> {
9833 if let NodeRequest::Sync { responder } = self { Some((responder)) } else { None }
9834 }
9835
9836 #[allow(irrefutable_let_patterns)]
9837 pub fn into_close(self) -> Option<(NodeControlHandle)> {
9838 if let NodeRequest::Close { control_handle } = self { Some((control_handle)) } else { None }
9839 }
9840
9841 #[allow(irrefutable_let_patterns)]
9842 pub fn into_set_name(self) -> Option<(u32, String, NodeControlHandle)> {
9843 if let NodeRequest::SetName { priority, name, control_handle } = self {
9844 Some((priority, name, control_handle))
9845 } else {
9846 None
9847 }
9848 }
9849
9850 #[allow(irrefutable_let_patterns)]
9851 pub fn into_set_debug_client_info(self) -> Option<(String, u64, NodeControlHandle)> {
9852 if let NodeRequest::SetDebugClientInfo { name, id, control_handle } = self {
9853 Some((name, id, control_handle))
9854 } else {
9855 None
9856 }
9857 }
9858
9859 #[allow(irrefutable_let_patterns)]
9860 pub fn into_set_debug_timeout_log_deadline(self) -> Option<(i64, NodeControlHandle)> {
9861 if let NodeRequest::SetDebugTimeoutLogDeadline { deadline, control_handle } = self {
9862 Some((deadline, control_handle))
9863 } else {
9864 None
9865 }
9866 }
9867
9868 #[allow(irrefutable_let_patterns)]
9869 pub fn into_set_verbose_logging(self) -> Option<(NodeControlHandle)> {
9870 if let NodeRequest::SetVerboseLogging { control_handle } = self {
9871 Some((control_handle))
9872 } else {
9873 None
9874 }
9875 }
9876
9877 #[allow(irrefutable_let_patterns)]
9878 pub fn into_get_node_ref(self) -> Option<(NodeGetNodeRefResponder)> {
9879 if let NodeRequest::GetNodeRef { responder } = self { Some((responder)) } else { None }
9880 }
9881
9882 #[allow(irrefutable_let_patterns)]
9883 pub fn into_is_alternate_for(self) -> Option<(fidl::Event, NodeIsAlternateForResponder)> {
9884 if let NodeRequest::IsAlternateFor { node_ref, responder } = self {
9885 Some((node_ref, responder))
9886 } else {
9887 None
9888 }
9889 }
9890
9891 /// Name of the method defined in FIDL
9892 pub fn method_name(&self) -> &'static str {
9893 match *self {
9894 NodeRequest::Sync { .. } => "sync",
9895 NodeRequest::Close { .. } => "close",
9896 NodeRequest::SetName { .. } => "set_name",
9897 NodeRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
9898 NodeRequest::SetDebugTimeoutLogDeadline { .. } => "set_debug_timeout_log_deadline",
9899 NodeRequest::SetVerboseLogging { .. } => "set_verbose_logging",
9900 NodeRequest::GetNodeRef { .. } => "get_node_ref",
9901 NodeRequest::IsAlternateFor { .. } => "is_alternate_for",
9902 }
9903 }
9904}
9905
9906#[derive(Debug, Clone)]
9907pub struct NodeControlHandle {
9908 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9909}
9910
9911impl fidl::endpoints::ControlHandle for NodeControlHandle {
9912 fn shutdown(&self) {
9913 self.inner.shutdown()
9914 }
9915
9916 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
9917 self.inner.shutdown_with_epitaph(status)
9918 }
9919
9920 fn is_closed(&self) -> bool {
9921 self.inner.channel().is_closed()
9922 }
9923 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
9924 self.inner.channel().on_closed()
9925 }
9926
9927 #[cfg(target_os = "fuchsia")]
9928 fn signal_peer(
9929 &self,
9930 clear_mask: zx::Signals,
9931 set_mask: zx::Signals,
9932 ) -> Result<(), zx_status::Status> {
9933 use fidl::Peered;
9934 self.inner.channel().signal_peer(clear_mask, set_mask)
9935 }
9936}
9937
9938impl NodeControlHandle {}
9939
9940#[must_use = "FIDL methods require a response to be sent"]
9941#[derive(Debug)]
9942pub struct NodeSyncResponder {
9943 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
9944 tx_id: u32,
9945}
9946
9947/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
9948/// if the responder is dropped without sending a response, so that the client
9949/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
9950impl std::ops::Drop for NodeSyncResponder {
9951 fn drop(&mut self) {
9952 self.control_handle.shutdown();
9953 // Safety: drops once, never accessed again
9954 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9955 }
9956}
9957
9958impl fidl::endpoints::Responder for NodeSyncResponder {
9959 type ControlHandle = NodeControlHandle;
9960
9961 fn control_handle(&self) -> &NodeControlHandle {
9962 &self.control_handle
9963 }
9964
9965 fn drop_without_shutdown(mut self) {
9966 // Safety: drops once, never accessed again due to mem::forget
9967 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
9968 // Prevent Drop from running (which would shut down the channel)
9969 std::mem::forget(self);
9970 }
9971}
9972
9973impl NodeSyncResponder {
9974 /// Sends a response to the FIDL transaction.
9975 ///
9976 /// Sets the channel to shutdown if an error occurs.
9977 pub fn send(self) -> Result<(), fidl::Error> {
9978 let _result = self.send_raw();
9979 if _result.is_err() {
9980 self.control_handle.shutdown();
9981 }
9982 self.drop_without_shutdown();
9983 _result
9984 }
9985
9986 /// Similar to "send" but does not shutdown the channel if an error occurs.
9987 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
9988 let _result = self.send_raw();
9989 self.drop_without_shutdown();
9990 _result
9991 }
9992
9993 fn send_raw(&self) -> Result<(), fidl::Error> {
9994 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
9995 (),
9996 self.tx_id,
9997 0x4577e238ae26291,
9998 fidl::encoding::DynamicFlags::empty(),
9999 )
10000 }
10001}
10002
10003#[must_use = "FIDL methods require a response to be sent"]
10004#[derive(Debug)]
10005pub struct NodeGetNodeRefResponder {
10006 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
10007 tx_id: u32,
10008}
10009
10010/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
10011/// if the responder is dropped without sending a response, so that the client
10012/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
10013impl std::ops::Drop for NodeGetNodeRefResponder {
10014 fn drop(&mut self) {
10015 self.control_handle.shutdown();
10016 // Safety: drops once, never accessed again
10017 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10018 }
10019}
10020
10021impl fidl::endpoints::Responder for NodeGetNodeRefResponder {
10022 type ControlHandle = NodeControlHandle;
10023
10024 fn control_handle(&self) -> &NodeControlHandle {
10025 &self.control_handle
10026 }
10027
10028 fn drop_without_shutdown(mut self) {
10029 // Safety: drops once, never accessed again due to mem::forget
10030 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10031 // Prevent Drop from running (which would shut down the channel)
10032 std::mem::forget(self);
10033 }
10034}
10035
10036impl NodeGetNodeRefResponder {
10037 /// Sends a response to the FIDL transaction.
10038 ///
10039 /// Sets the channel to shutdown if an error occurs.
10040 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10041 let _result = self.send_raw(node_ref);
10042 if _result.is_err() {
10043 self.control_handle.shutdown();
10044 }
10045 self.drop_without_shutdown();
10046 _result
10047 }
10048
10049 /// Similar to "send" but does not shutdown the channel if an error occurs.
10050 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10051 let _result = self.send_raw(node_ref);
10052 self.drop_without_shutdown();
10053 _result
10054 }
10055
10056 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10057 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
10058 (node_ref,),
10059 self.tx_id,
10060 0x467b7c75c35c3b84,
10061 fidl::encoding::DynamicFlags::empty(),
10062 )
10063 }
10064}
10065
10066#[must_use = "FIDL methods require a response to be sent"]
10067#[derive(Debug)]
10068pub struct NodeIsAlternateForResponder {
10069 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
10070 tx_id: u32,
10071}
10072
10073/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
10074/// if the responder is dropped without sending a response, so that the client
10075/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
10076impl std::ops::Drop for NodeIsAlternateForResponder {
10077 fn drop(&mut self) {
10078 self.control_handle.shutdown();
10079 // Safety: drops once, never accessed again
10080 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10081 }
10082}
10083
10084impl fidl::endpoints::Responder for NodeIsAlternateForResponder {
10085 type ControlHandle = NodeControlHandle;
10086
10087 fn control_handle(&self) -> &NodeControlHandle {
10088 &self.control_handle
10089 }
10090
10091 fn drop_without_shutdown(mut self) {
10092 // Safety: drops once, never accessed again due to mem::forget
10093 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10094 // Prevent Drop from running (which would shut down the channel)
10095 std::mem::forget(self);
10096 }
10097}
10098
10099impl NodeIsAlternateForResponder {
10100 /// Sends a response to the FIDL transaction.
10101 ///
10102 /// Sets the channel to shutdown if an error occurs.
10103 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10104 let _result = self.send_raw(result);
10105 if _result.is_err() {
10106 self.control_handle.shutdown();
10107 }
10108 self.drop_without_shutdown();
10109 _result
10110 }
10111
10112 /// Similar to "send" but does not shutdown the channel if an error occurs.
10113 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10114 let _result = self.send_raw(result);
10115 self.drop_without_shutdown();
10116 _result
10117 }
10118
10119 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10120 self.control_handle
10121 .inner
10122 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
10123 result.map(|is_alternate| (is_alternate,)),
10124 self.tx_id,
10125 0x33a2a7aff2776c07,
10126 fidl::encoding::DynamicFlags::empty(),
10127 )
10128 }
10129}
10130
10131#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
10132pub struct SecureMemMarker;
10133
10134impl fidl::endpoints::ProtocolMarker for SecureMemMarker {
10135 type Proxy = SecureMemProxy;
10136 type RequestStream = SecureMemRequestStream;
10137 #[cfg(target_os = "fuchsia")]
10138 type SynchronousProxy = SecureMemSynchronousProxy;
10139
10140 const DEBUG_NAME: &'static str = "(anonymous) SecureMem";
10141}
10142pub type SecureMemGetPhysicalSecureHeapsResult = Result<SecureHeapsAndRanges, i32>;
10143pub type SecureMemGetPhysicalSecureHeapPropertiesResult = Result<SecureHeapProperties, i32>;
10144pub type SecureMemAddSecureHeapPhysicalRangeResult = Result<(), i32>;
10145pub type SecureMemDeleteSecureHeapPhysicalRangeResult = Result<(), i32>;
10146pub type SecureMemModifySecureHeapPhysicalRangeResult = Result<(), i32>;
10147pub type SecureMemZeroSubRangeResult = Result<(), i32>;
10148
10149pub trait SecureMemProxyInterface: Send + Sync {
10150 type GetPhysicalSecureHeapsResponseFut: std::future::Future<Output = Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error>>
10151 + Send;
10152 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut;
10153 type GetPhysicalSecureHeapPropertiesResponseFut: std::future::Future<
10154 Output = Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error>,
10155 > + Send;
10156 fn r#get_physical_secure_heap_properties(
10157 &self,
10158 entire_heap: &SecureHeapAndRange,
10159 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut;
10160 type AddSecureHeapPhysicalRangeResponseFut: std::future::Future<Output = Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error>>
10161 + Send;
10162 fn r#add_secure_heap_physical_range(
10163 &self,
10164 heap_range: &SecureHeapAndRange,
10165 ) -> Self::AddSecureHeapPhysicalRangeResponseFut;
10166 type DeleteSecureHeapPhysicalRangeResponseFut: std::future::Future<
10167 Output = Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error>,
10168 > + Send;
10169 fn r#delete_secure_heap_physical_range(
10170 &self,
10171 heap_range: &SecureHeapAndRange,
10172 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut;
10173 type ModifySecureHeapPhysicalRangeResponseFut: std::future::Future<
10174 Output = Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error>,
10175 > + Send;
10176 fn r#modify_secure_heap_physical_range(
10177 &self,
10178 range_modification: &SecureHeapAndRangeModification,
10179 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut;
10180 type ZeroSubRangeResponseFut: std::future::Future<Output = Result<SecureMemZeroSubRangeResult, fidl::Error>>
10181 + Send;
10182 fn r#zero_sub_range(
10183 &self,
10184 is_covering_range_explicit: bool,
10185 heap_range: &SecureHeapAndRange,
10186 ) -> Self::ZeroSubRangeResponseFut;
10187}
10188#[derive(Debug)]
10189#[cfg(target_os = "fuchsia")]
10190pub struct SecureMemSynchronousProxy {
10191 client: fidl::client::sync::Client,
10192}
10193
10194#[cfg(target_os = "fuchsia")]
10195impl fidl::endpoints::SynchronousProxy for SecureMemSynchronousProxy {
10196 type Proxy = SecureMemProxy;
10197 type Protocol = SecureMemMarker;
10198
10199 fn from_channel(inner: fidl::Channel) -> Self {
10200 Self::new(inner)
10201 }
10202
10203 fn into_channel(self) -> fidl::Channel {
10204 self.client.into_channel()
10205 }
10206
10207 fn as_channel(&self) -> &fidl::Channel {
10208 self.client.as_channel()
10209 }
10210}
10211
10212#[cfg(target_os = "fuchsia")]
10213impl SecureMemSynchronousProxy {
10214 pub fn new(channel: fidl::Channel) -> Self {
10215 let protocol_name = <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
10216 Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
10217 }
10218
10219 pub fn into_channel(self) -> fidl::Channel {
10220 self.client.into_channel()
10221 }
10222
10223 /// Waits until an event arrives and returns it. It is safe for other
10224 /// threads to make concurrent requests while waiting for an event.
10225 pub fn wait_for_event(
10226 &self,
10227 deadline: zx::MonotonicInstant,
10228 ) -> Result<SecureMemEvent, fidl::Error> {
10229 SecureMemEvent::decode(self.client.wait_for_event(deadline)?)
10230 }
10231
10232 /// Gets the physical address and length of any secure heap whose physical
10233 /// range is configured via the TEE.
10234 ///
10235 /// Presently, these will be fixed physical addresses and lengths, with the
10236 /// location plumbed via the TEE.
10237 ///
10238 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
10239 /// when there isn't any special heap-specific per-VMO setup or teardown
10240 /// required.
10241 ///
10242 /// The physical range must be secured/protected by the TEE before the
10243 /// securemem driver responds to this request with success.
10244 ///
10245 /// Sysmem should only call this once. Returning zero heaps is not a
10246 /// failure.
10247 ///
10248 /// Errors:
10249 /// * ZX_ERR_BAD_STATE - called more than once.
10250 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10251 /// with TEE which doesn't generate zx_status_t errors).
10252 /// * other errors are allowed; any other errors should be treated the same
10253 /// as ZX_ERR_INTERNAL.
10254 pub fn r#get_physical_secure_heaps(
10255 &self,
10256 ___deadline: zx::MonotonicInstant,
10257 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
10258 let _response = self.client.send_query::<
10259 fidl::encoding::EmptyPayload,
10260 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapsResponse, i32>,
10261 >(
10262 (),
10263 0x782319d6ce7fa05,
10264 fidl::encoding::DynamicFlags::empty(),
10265 ___deadline,
10266 )?;
10267 Ok(_response.map(|x| x.heaps))
10268 }
10269
10270 /// This request from sysmem to the securemem driver gets the properties of
10271 /// a protected/secure heap.
10272 ///
10273 /// This only handles heaps with a single contiguous physical extent.
10274 ///
10275 /// The heap's entire physical range is indicated in case this request needs
10276 /// some physical space to auto-detect how many ranges are REE-usable. Any
10277 /// temporary HW protection ranges will be deleted before this request
10278 /// completes.
10279 pub fn r#get_physical_secure_heap_properties(
10280 &self,
10281 mut entire_heap: &SecureHeapAndRange,
10282 ___deadline: zx::MonotonicInstant,
10283 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
10284 let _response = self.client.send_query::<
10285 SecureMemGetPhysicalSecureHeapPropertiesRequest,
10286 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapPropertiesResponse, i32>,
10287 >(
10288 (entire_heap,),
10289 0x26404e23f1271214,
10290 fidl::encoding::DynamicFlags::empty(),
10291 ___deadline,
10292 )?;
10293 Ok(_response.map(|x| x.properties))
10294 }
10295
10296 /// This request from sysmem to the securemem driver conveys a physical
10297 /// range to add, for a heap whose physical range(s) are set up via
10298 /// sysmem.
10299 ///
10300 /// Only sysmem can call this because only sysmem is handed the client end
10301 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10302 /// securemem driver is the server end of this protocol.
10303 ///
10304 /// The securemem driver must configure all the covered offsets as protected
10305 /// before responding to this message with success.
10306 ///
10307 /// On failure, the securemem driver must ensure the protected range was not
10308 /// created.
10309 ///
10310 /// Sysmem must only call this up to once if dynamic_protection_ranges
10311 /// false.
10312 ///
10313 /// If dynamic_protection_ranges is true, sysmem can call this multiple
10314 /// times as long as the current number of ranges never exceeds
10315 /// max_protected_range_count.
10316 ///
10317 /// The caller must not attempt to add a range that matches an
10318 /// already-existing range. Added ranges can overlap each other as long as
10319 /// no two ranges match exactly.
10320 ///
10321 /// Errors:
10322 /// * ZX_ERR_BAD_STATE - called more than once when
10323 /// !dynamic_protection_ranges. Adding a heap that would cause overall
10324 /// heap count to exceed max_protected_range_count.
10325 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10326 /// to protected_range_granularity.
10327 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10328 /// with TEE which doesn't generate zx_status_t errors).
10329 /// * other errors are possible, such as from communication failures or
10330 /// server propagation of zx_status_t failures.
10331 pub fn r#add_secure_heap_physical_range(
10332 &self,
10333 mut heap_range: &SecureHeapAndRange,
10334 ___deadline: zx::MonotonicInstant,
10335 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
10336 let _response = self.client.send_query::<
10337 SecureMemAddSecureHeapPhysicalRangeRequest,
10338 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10339 >(
10340 (heap_range,),
10341 0x1ca1abcee8a0b33e,
10342 fidl::encoding::DynamicFlags::empty(),
10343 ___deadline,
10344 )?;
10345 Ok(_response.map(|x| x))
10346 }
10347
10348 /// This request from sysmem to the securemem driver conveys a physical
10349 /// range to delete, for a heap whose physical range(s) are set up via
10350 /// sysmem.
10351 ///
10352 /// Only sysmem can call this because only sysmem is handed the client end
10353 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10354 /// securemem driver is the server end of this protocol.
10355 ///
10356 /// The securemem driver must configure all the covered offsets as not
10357 /// protected before responding to this message with success.
10358 ///
10359 /// On failure, the securemem driver must ensure the protected range was not
10360 /// deleted.
10361 ///
10362 /// Sysmem must not call this if dynamic_protection_ranges false.
10363 ///
10364 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10365 /// on various ranges that exist at the time of the call.
10366 ///
10367 /// If any portion of the range being deleted is not also covered by another
10368 /// protected range, then any ongoing DMA to any part of the entire range
10369 /// may be interrupted / may fail, potentially in a way that's disruptive to
10370 /// the entire system (bus lockup or similar, depending on device details).
10371 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
10372 /// any portion of the range being deleted, unless the caller has other
10373 /// active ranges covering every block of the range being deleted. Ongoing
10374 /// DMA to/from blocks outside the range being deleted is never impacted by
10375 /// the deletion.
10376 ///
10377 /// Errors:
10378 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10379 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10380 /// to protected_range_granularity.
10381 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10382 /// with TEE which doesn't generate zx_status_t errors).
10383 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10384 /// * other errors are possible, such as from communication failures or
10385 /// server propagation of zx_status_t failures.
10386 pub fn r#delete_secure_heap_physical_range(
10387 &self,
10388 mut heap_range: &SecureHeapAndRange,
10389 ___deadline: zx::MonotonicInstant,
10390 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
10391 let _response = self.client.send_query::<
10392 SecureMemDeleteSecureHeapPhysicalRangeRequest,
10393 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10394 >(
10395 (heap_range,),
10396 0x728a953e56df92ee,
10397 fidl::encoding::DynamicFlags::empty(),
10398 ___deadline,
10399 )?;
10400 Ok(_response.map(|x| x))
10401 }
10402
10403 /// This request from sysmem to the securemem driver conveys a physical
10404 /// range to modify and its new base and length, for a heap whose physical
10405 /// range(s) are set up via sysmem.
10406 ///
10407 /// Only sysmem can call this because only sysmem is handed the client end
10408 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10409 /// securemem driver is the server end of this protocol.
10410 ///
10411 /// The securemem driver must configure the range to cover only the new
10412 /// offsets before responding to this message with success.
10413 ///
10414 /// On failure, the securemem driver must ensure the range was not changed.
10415 ///
10416 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
10417 /// must not call this if !is_mod_protected_range_available.
10418 ///
10419 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10420 /// on various ranges that exist at the time of the call.
10421 ///
10422 /// The range must only be modified at one end or the other, but not both.
10423 /// If the range is getting shorter, and the un-covered blocks are not
10424 /// covered by other active ranges, any ongoing DMA to the entire range
10425 /// that's geting shorter may fail in a way that disrupts the entire system
10426 /// (bus lockup or similar), so the caller must ensure that no DMA is
10427 /// ongoing to any portion of a range that is getting shorter, unless the
10428 /// blocks being un-covered by the modification to this range are all
10429 /// covered by other active ranges, in which case no disruption to ongoing
10430 /// DMA will occur.
10431 ///
10432 /// If a range is modified to become <= zero length, the range is deleted.
10433 ///
10434 /// Errors:
10435 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10436 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
10437 /// that doesn't conform to protected_range_granularity, or old_range
10438 /// and new_range differ in both begin and end (disallowed).
10439 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10440 /// with TEE which doesn't generate zx_status_t errors).
10441 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10442 /// * other errors are possible, such as from communication failures or
10443 /// server propagation of zx_status_t failures.
10444 pub fn r#modify_secure_heap_physical_range(
10445 &self,
10446 mut range_modification: &SecureHeapAndRangeModification,
10447 ___deadline: zx::MonotonicInstant,
10448 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
10449 let _response = self.client.send_query::<
10450 SecureMemModifySecureHeapPhysicalRangeRequest,
10451 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10452 >(
10453 (range_modification,),
10454 0x154fbfa3646a890d,
10455 fidl::encoding::DynamicFlags::empty(),
10456 ___deadline,
10457 )?;
10458 Ok(_response.map(|x| x))
10459 }
10460
10461 /// Zero a sub-range of a currently-existing physical range added via
10462 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
10463 /// exactly one physical range, and must not overlap with any other
10464 /// physical range.
10465 ///
10466 /// is_covering_range_explicit - When true, the covering range must be one
10467 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
10468 /// possibly modified since. When false, the covering range must not
10469 /// be one of the ranges explicitly created via
10470 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
10471 /// a covering range not created via AddSecureHeapPhysicalRange(). The
10472 /// covering range is typically the entire physical range (or a range
10473 /// which covers even more) of a heap configured by the TEE and whose
10474 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
10475 ///
10476 /// Ongoing DMA is not disrupted by this request.
10477 pub fn r#zero_sub_range(
10478 &self,
10479 mut is_covering_range_explicit: bool,
10480 mut heap_range: &SecureHeapAndRange,
10481 ___deadline: zx::MonotonicInstant,
10482 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
10483 let _response = self.client.send_query::<
10484 SecureMemZeroSubRangeRequest,
10485 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10486 >(
10487 (is_covering_range_explicit, heap_range,),
10488 0x7480f72bb5bc7e5b,
10489 fidl::encoding::DynamicFlags::empty(),
10490 ___deadline,
10491 )?;
10492 Ok(_response.map(|x| x))
10493 }
10494}
10495
10496#[cfg(target_os = "fuchsia")]
10497impl From<SecureMemSynchronousProxy> for zx::NullableHandle {
10498 fn from(value: SecureMemSynchronousProxy) -> Self {
10499 value.into_channel().into()
10500 }
10501}
10502
10503#[cfg(target_os = "fuchsia")]
10504impl From<fidl::Channel> for SecureMemSynchronousProxy {
10505 fn from(value: fidl::Channel) -> Self {
10506 Self::new(value)
10507 }
10508}
10509
10510#[cfg(target_os = "fuchsia")]
10511impl fidl::endpoints::FromClient for SecureMemSynchronousProxy {
10512 type Protocol = SecureMemMarker;
10513
10514 fn from_client(value: fidl::endpoints::ClientEnd<SecureMemMarker>) -> Self {
10515 Self::new(value.into_channel())
10516 }
10517}
10518
10519#[derive(Debug, Clone)]
10520pub struct SecureMemProxy {
10521 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
10522}
10523
10524impl fidl::endpoints::Proxy for SecureMemProxy {
10525 type Protocol = SecureMemMarker;
10526
10527 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
10528 Self::new(inner)
10529 }
10530
10531 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
10532 self.client.into_channel().map_err(|client| Self { client })
10533 }
10534
10535 fn as_channel(&self) -> &::fidl::AsyncChannel {
10536 self.client.as_channel()
10537 }
10538}
10539
10540impl SecureMemProxy {
10541 /// Create a new Proxy for fuchsia.sysmem/SecureMem.
10542 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
10543 let protocol_name = <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
10544 Self { client: fidl::client::Client::new(channel, protocol_name) }
10545 }
10546
10547 /// Get a Stream of events from the remote end of the protocol.
10548 ///
10549 /// # Panics
10550 ///
10551 /// Panics if the event stream was already taken.
10552 pub fn take_event_stream(&self) -> SecureMemEventStream {
10553 SecureMemEventStream { event_receiver: self.client.take_event_receiver() }
10554 }
10555
10556 /// Gets the physical address and length of any secure heap whose physical
10557 /// range is configured via the TEE.
10558 ///
10559 /// Presently, these will be fixed physical addresses and lengths, with the
10560 /// location plumbed via the TEE.
10561 ///
10562 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
10563 /// when there isn't any special heap-specific per-VMO setup or teardown
10564 /// required.
10565 ///
10566 /// The physical range must be secured/protected by the TEE before the
10567 /// securemem driver responds to this request with success.
10568 ///
10569 /// Sysmem should only call this once. Returning zero heaps is not a
10570 /// failure.
10571 ///
10572 /// Errors:
10573 /// * ZX_ERR_BAD_STATE - called more than once.
10574 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10575 /// with TEE which doesn't generate zx_status_t errors).
10576 /// * other errors are allowed; any other errors should be treated the same
10577 /// as ZX_ERR_INTERNAL.
10578 pub fn r#get_physical_secure_heaps(
10579 &self,
10580 ) -> fidl::client::QueryResponseFut<
10581 SecureMemGetPhysicalSecureHeapsResult,
10582 fidl::encoding::DefaultFuchsiaResourceDialect,
10583 > {
10584 SecureMemProxyInterface::r#get_physical_secure_heaps(self)
10585 }
10586
10587 /// This request from sysmem to the securemem driver gets the properties of
10588 /// a protected/secure heap.
10589 ///
10590 /// This only handles heaps with a single contiguous physical extent.
10591 ///
10592 /// The heap's entire physical range is indicated in case this request needs
10593 /// some physical space to auto-detect how many ranges are REE-usable. Any
10594 /// temporary HW protection ranges will be deleted before this request
10595 /// completes.
10596 pub fn r#get_physical_secure_heap_properties(
10597 &self,
10598 mut entire_heap: &SecureHeapAndRange,
10599 ) -> fidl::client::QueryResponseFut<
10600 SecureMemGetPhysicalSecureHeapPropertiesResult,
10601 fidl::encoding::DefaultFuchsiaResourceDialect,
10602 > {
10603 SecureMemProxyInterface::r#get_physical_secure_heap_properties(self, entire_heap)
10604 }
10605
10606 /// This request from sysmem to the securemem driver conveys a physical
10607 /// range to add, for a heap whose physical range(s) are set up via
10608 /// sysmem.
10609 ///
10610 /// Only sysmem can call this because only sysmem is handed the client end
10611 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10612 /// securemem driver is the server end of this protocol.
10613 ///
10614 /// The securemem driver must configure all the covered offsets as protected
10615 /// before responding to this message with success.
10616 ///
10617 /// On failure, the securemem driver must ensure the protected range was not
10618 /// created.
10619 ///
10620 /// Sysmem must only call this up to once if dynamic_protection_ranges
10621 /// false.
10622 ///
10623 /// If dynamic_protection_ranges is true, sysmem can call this multiple
10624 /// times as long as the current number of ranges never exceeds
10625 /// max_protected_range_count.
10626 ///
10627 /// The caller must not attempt to add a range that matches an
10628 /// already-existing range. Added ranges can overlap each other as long as
10629 /// no two ranges match exactly.
10630 ///
10631 /// Errors:
10632 /// * ZX_ERR_BAD_STATE - called more than once when
10633 /// !dynamic_protection_ranges. Adding a heap that would cause overall
10634 /// heap count to exceed max_protected_range_count.
10635 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10636 /// to protected_range_granularity.
10637 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10638 /// with TEE which doesn't generate zx_status_t errors).
10639 /// * other errors are possible, such as from communication failures or
10640 /// server propagation of zx_status_t failures.
10641 pub fn r#add_secure_heap_physical_range(
10642 &self,
10643 mut heap_range: &SecureHeapAndRange,
10644 ) -> fidl::client::QueryResponseFut<
10645 SecureMemAddSecureHeapPhysicalRangeResult,
10646 fidl::encoding::DefaultFuchsiaResourceDialect,
10647 > {
10648 SecureMemProxyInterface::r#add_secure_heap_physical_range(self, heap_range)
10649 }
10650
10651 /// This request from sysmem to the securemem driver conveys a physical
10652 /// range to delete, for a heap whose physical range(s) are set up via
10653 /// sysmem.
10654 ///
10655 /// Only sysmem can call this because only sysmem is handed the client end
10656 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10657 /// securemem driver is the server end of this protocol.
10658 ///
10659 /// The securemem driver must configure all the covered offsets as not
10660 /// protected before responding to this message with success.
10661 ///
10662 /// On failure, the securemem driver must ensure the protected range was not
10663 /// deleted.
10664 ///
10665 /// Sysmem must not call this if dynamic_protection_ranges false.
10666 ///
10667 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10668 /// on various ranges that exist at the time of the call.
10669 ///
10670 /// If any portion of the range being deleted is not also covered by another
10671 /// protected range, then any ongoing DMA to any part of the entire range
10672 /// may be interrupted / may fail, potentially in a way that's disruptive to
10673 /// the entire system (bus lockup or similar, depending on device details).
10674 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
10675 /// any portion of the range being deleted, unless the caller has other
10676 /// active ranges covering every block of the range being deleted. Ongoing
10677 /// DMA to/from blocks outside the range being deleted is never impacted by
10678 /// the deletion.
10679 ///
10680 /// Errors:
10681 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10682 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10683 /// to protected_range_granularity.
10684 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10685 /// with TEE which doesn't generate zx_status_t errors).
10686 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10687 /// * other errors are possible, such as from communication failures or
10688 /// server propagation of zx_status_t failures.
10689 pub fn r#delete_secure_heap_physical_range(
10690 &self,
10691 mut heap_range: &SecureHeapAndRange,
10692 ) -> fidl::client::QueryResponseFut<
10693 SecureMemDeleteSecureHeapPhysicalRangeResult,
10694 fidl::encoding::DefaultFuchsiaResourceDialect,
10695 > {
10696 SecureMemProxyInterface::r#delete_secure_heap_physical_range(self, heap_range)
10697 }
10698
10699 /// This request from sysmem to the securemem driver conveys a physical
10700 /// range to modify and its new base and length, for a heap whose physical
10701 /// range(s) are set up via sysmem.
10702 ///
10703 /// Only sysmem can call this because only sysmem is handed the client end
10704 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10705 /// securemem driver is the server end of this protocol.
10706 ///
10707 /// The securemem driver must configure the range to cover only the new
10708 /// offsets before responding to this message with success.
10709 ///
10710 /// On failure, the securemem driver must ensure the range was not changed.
10711 ///
10712 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
10713 /// must not call this if !is_mod_protected_range_available.
10714 ///
10715 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10716 /// on various ranges that exist at the time of the call.
10717 ///
10718 /// The range must only be modified at one end or the other, but not both.
10719 /// If the range is getting shorter, and the un-covered blocks are not
10720 /// covered by other active ranges, any ongoing DMA to the entire range
10721 /// that's geting shorter may fail in a way that disrupts the entire system
10722 /// (bus lockup or similar), so the caller must ensure that no DMA is
10723 /// ongoing to any portion of a range that is getting shorter, unless the
10724 /// blocks being un-covered by the modification to this range are all
10725 /// covered by other active ranges, in which case no disruption to ongoing
10726 /// DMA will occur.
10727 ///
10728 /// If a range is modified to become <= zero length, the range is deleted.
10729 ///
10730 /// Errors:
10731 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10732 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
10733 /// that doesn't conform to protected_range_granularity, or old_range
10734 /// and new_range differ in both begin and end (disallowed).
10735 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10736 /// with TEE which doesn't generate zx_status_t errors).
10737 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10738 /// * other errors are possible, such as from communication failures or
10739 /// server propagation of zx_status_t failures.
10740 pub fn r#modify_secure_heap_physical_range(
10741 &self,
10742 mut range_modification: &SecureHeapAndRangeModification,
10743 ) -> fidl::client::QueryResponseFut<
10744 SecureMemModifySecureHeapPhysicalRangeResult,
10745 fidl::encoding::DefaultFuchsiaResourceDialect,
10746 > {
10747 SecureMemProxyInterface::r#modify_secure_heap_physical_range(self, range_modification)
10748 }
10749
10750 /// Zero a sub-range of a currently-existing physical range added via
10751 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
10752 /// exactly one physical range, and must not overlap with any other
10753 /// physical range.
10754 ///
10755 /// is_covering_range_explicit - When true, the covering range must be one
10756 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
10757 /// possibly modified since. When false, the covering range must not
10758 /// be one of the ranges explicitly created via
10759 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
10760 /// a covering range not created via AddSecureHeapPhysicalRange(). The
10761 /// covering range is typically the entire physical range (or a range
10762 /// which covers even more) of a heap configured by the TEE and whose
10763 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
10764 ///
10765 /// Ongoing DMA is not disrupted by this request.
10766 pub fn r#zero_sub_range(
10767 &self,
10768 mut is_covering_range_explicit: bool,
10769 mut heap_range: &SecureHeapAndRange,
10770 ) -> fidl::client::QueryResponseFut<
10771 SecureMemZeroSubRangeResult,
10772 fidl::encoding::DefaultFuchsiaResourceDialect,
10773 > {
10774 SecureMemProxyInterface::r#zero_sub_range(self, is_covering_range_explicit, heap_range)
10775 }
10776}
10777
10778impl SecureMemProxyInterface for SecureMemProxy {
10779 type GetPhysicalSecureHeapsResponseFut = fidl::client::QueryResponseFut<
10780 SecureMemGetPhysicalSecureHeapsResult,
10781 fidl::encoding::DefaultFuchsiaResourceDialect,
10782 >;
10783 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut {
10784 fn _decode(
10785 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10786 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
10787 let _response = fidl::client::decode_transaction_body::<
10788 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapsResponse, i32>,
10789 fidl::encoding::DefaultFuchsiaResourceDialect,
10790 0x782319d6ce7fa05,
10791 >(_buf?)?;
10792 Ok(_response.map(|x| x.heaps))
10793 }
10794 self.client.send_query_and_decode::<
10795 fidl::encoding::EmptyPayload,
10796 SecureMemGetPhysicalSecureHeapsResult,
10797 >(
10798 (),
10799 0x782319d6ce7fa05,
10800 fidl::encoding::DynamicFlags::empty(),
10801 _decode,
10802 )
10803 }
10804
10805 type GetPhysicalSecureHeapPropertiesResponseFut = fidl::client::QueryResponseFut<
10806 SecureMemGetPhysicalSecureHeapPropertiesResult,
10807 fidl::encoding::DefaultFuchsiaResourceDialect,
10808 >;
10809 fn r#get_physical_secure_heap_properties(
10810 &self,
10811 mut entire_heap: &SecureHeapAndRange,
10812 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut {
10813 fn _decode(
10814 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10815 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
10816 let _response = fidl::client::decode_transaction_body::<
10817 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapPropertiesResponse, i32>,
10818 fidl::encoding::DefaultFuchsiaResourceDialect,
10819 0x26404e23f1271214,
10820 >(_buf?)?;
10821 Ok(_response.map(|x| x.properties))
10822 }
10823 self.client.send_query_and_decode::<
10824 SecureMemGetPhysicalSecureHeapPropertiesRequest,
10825 SecureMemGetPhysicalSecureHeapPropertiesResult,
10826 >(
10827 (entire_heap,),
10828 0x26404e23f1271214,
10829 fidl::encoding::DynamicFlags::empty(),
10830 _decode,
10831 )
10832 }
10833
10834 type AddSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10835 SecureMemAddSecureHeapPhysicalRangeResult,
10836 fidl::encoding::DefaultFuchsiaResourceDialect,
10837 >;
10838 fn r#add_secure_heap_physical_range(
10839 &self,
10840 mut heap_range: &SecureHeapAndRange,
10841 ) -> Self::AddSecureHeapPhysicalRangeResponseFut {
10842 fn _decode(
10843 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10844 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
10845 let _response = fidl::client::decode_transaction_body::<
10846 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10847 fidl::encoding::DefaultFuchsiaResourceDialect,
10848 0x1ca1abcee8a0b33e,
10849 >(_buf?)?;
10850 Ok(_response.map(|x| x))
10851 }
10852 self.client.send_query_and_decode::<
10853 SecureMemAddSecureHeapPhysicalRangeRequest,
10854 SecureMemAddSecureHeapPhysicalRangeResult,
10855 >(
10856 (heap_range,),
10857 0x1ca1abcee8a0b33e,
10858 fidl::encoding::DynamicFlags::empty(),
10859 _decode,
10860 )
10861 }
10862
10863 type DeleteSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10864 SecureMemDeleteSecureHeapPhysicalRangeResult,
10865 fidl::encoding::DefaultFuchsiaResourceDialect,
10866 >;
10867 fn r#delete_secure_heap_physical_range(
10868 &self,
10869 mut heap_range: &SecureHeapAndRange,
10870 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut {
10871 fn _decode(
10872 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10873 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
10874 let _response = fidl::client::decode_transaction_body::<
10875 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10876 fidl::encoding::DefaultFuchsiaResourceDialect,
10877 0x728a953e56df92ee,
10878 >(_buf?)?;
10879 Ok(_response.map(|x| x))
10880 }
10881 self.client.send_query_and_decode::<
10882 SecureMemDeleteSecureHeapPhysicalRangeRequest,
10883 SecureMemDeleteSecureHeapPhysicalRangeResult,
10884 >(
10885 (heap_range,),
10886 0x728a953e56df92ee,
10887 fidl::encoding::DynamicFlags::empty(),
10888 _decode,
10889 )
10890 }
10891
10892 type ModifySecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10893 SecureMemModifySecureHeapPhysicalRangeResult,
10894 fidl::encoding::DefaultFuchsiaResourceDialect,
10895 >;
10896 fn r#modify_secure_heap_physical_range(
10897 &self,
10898 mut range_modification: &SecureHeapAndRangeModification,
10899 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut {
10900 fn _decode(
10901 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10902 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
10903 let _response = fidl::client::decode_transaction_body::<
10904 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10905 fidl::encoding::DefaultFuchsiaResourceDialect,
10906 0x154fbfa3646a890d,
10907 >(_buf?)?;
10908 Ok(_response.map(|x| x))
10909 }
10910 self.client.send_query_and_decode::<
10911 SecureMemModifySecureHeapPhysicalRangeRequest,
10912 SecureMemModifySecureHeapPhysicalRangeResult,
10913 >(
10914 (range_modification,),
10915 0x154fbfa3646a890d,
10916 fidl::encoding::DynamicFlags::empty(),
10917 _decode,
10918 )
10919 }
10920
10921 type ZeroSubRangeResponseFut = fidl::client::QueryResponseFut<
10922 SecureMemZeroSubRangeResult,
10923 fidl::encoding::DefaultFuchsiaResourceDialect,
10924 >;
10925 fn r#zero_sub_range(
10926 &self,
10927 mut is_covering_range_explicit: bool,
10928 mut heap_range: &SecureHeapAndRange,
10929 ) -> Self::ZeroSubRangeResponseFut {
10930 fn _decode(
10931 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10932 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
10933 let _response = fidl::client::decode_transaction_body::<
10934 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10935 fidl::encoding::DefaultFuchsiaResourceDialect,
10936 0x7480f72bb5bc7e5b,
10937 >(_buf?)?;
10938 Ok(_response.map(|x| x))
10939 }
10940 self.client
10941 .send_query_and_decode::<SecureMemZeroSubRangeRequest, SecureMemZeroSubRangeResult>(
10942 (is_covering_range_explicit, heap_range),
10943 0x7480f72bb5bc7e5b,
10944 fidl::encoding::DynamicFlags::empty(),
10945 _decode,
10946 )
10947 }
10948}
10949
10950pub struct SecureMemEventStream {
10951 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
10952}
10953
10954impl std::marker::Unpin for SecureMemEventStream {}
10955
10956impl futures::stream::FusedStream for SecureMemEventStream {
10957 fn is_terminated(&self) -> bool {
10958 self.event_receiver.is_terminated()
10959 }
10960}
10961
10962impl futures::Stream for SecureMemEventStream {
10963 type Item = Result<SecureMemEvent, fidl::Error>;
10964
10965 fn poll_next(
10966 mut self: std::pin::Pin<&mut Self>,
10967 cx: &mut std::task::Context<'_>,
10968 ) -> std::task::Poll<Option<Self::Item>> {
10969 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
10970 &mut self.event_receiver,
10971 cx
10972 )?) {
10973 Some(buf) => std::task::Poll::Ready(Some(SecureMemEvent::decode(buf))),
10974 None => std::task::Poll::Ready(None),
10975 }
10976 }
10977}
10978
10979#[derive(Debug)]
10980pub enum SecureMemEvent {}
10981
10982impl SecureMemEvent {
10983 /// Decodes a message buffer as a [`SecureMemEvent`].
10984 fn decode(
10985 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
10986 ) -> Result<SecureMemEvent, fidl::Error> {
10987 let (bytes, _handles) = buf.split_mut();
10988 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
10989 debug_assert_eq!(tx_header.tx_id, 0);
10990 match tx_header.ordinal {
10991 _ => Err(fidl::Error::UnknownOrdinal {
10992 ordinal: tx_header.ordinal,
10993 protocol_name: <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
10994 }),
10995 }
10996 }
10997}
10998
10999/// A Stream of incoming requests for fuchsia.sysmem/SecureMem.
11000pub struct SecureMemRequestStream {
11001 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11002 is_terminated: bool,
11003}
11004
11005impl std::marker::Unpin for SecureMemRequestStream {}
11006
11007impl futures::stream::FusedStream for SecureMemRequestStream {
11008 fn is_terminated(&self) -> bool {
11009 self.is_terminated
11010 }
11011}
11012
11013impl fidl::endpoints::RequestStream for SecureMemRequestStream {
11014 type Protocol = SecureMemMarker;
11015 type ControlHandle = SecureMemControlHandle;
11016
11017 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
11018 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
11019 }
11020
11021 fn control_handle(&self) -> Self::ControlHandle {
11022 SecureMemControlHandle { inner: self.inner.clone() }
11023 }
11024
11025 fn into_inner(
11026 self,
11027 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
11028 {
11029 (self.inner, self.is_terminated)
11030 }
11031
11032 fn from_inner(
11033 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11034 is_terminated: bool,
11035 ) -> Self {
11036 Self { inner, is_terminated }
11037 }
11038}
11039
11040impl futures::Stream for SecureMemRequestStream {
11041 type Item = Result<SecureMemRequest, fidl::Error>;
11042
11043 fn poll_next(
11044 mut self: std::pin::Pin<&mut Self>,
11045 cx: &mut std::task::Context<'_>,
11046 ) -> std::task::Poll<Option<Self::Item>> {
11047 let this = &mut *self;
11048 if this.inner.check_shutdown(cx) {
11049 this.is_terminated = true;
11050 return std::task::Poll::Ready(None);
11051 }
11052 if this.is_terminated {
11053 panic!("polled SecureMemRequestStream after completion");
11054 }
11055 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
11056 |bytes, handles| {
11057 match this.inner.channel().read_etc(cx, bytes, handles) {
11058 std::task::Poll::Ready(Ok(())) => {}
11059 std::task::Poll::Pending => return std::task::Poll::Pending,
11060 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
11061 this.is_terminated = true;
11062 return std::task::Poll::Ready(None);
11063 }
11064 std::task::Poll::Ready(Err(e)) => {
11065 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
11066 e.into(),
11067 ))));
11068 }
11069 }
11070
11071 // A message has been received from the channel
11072 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
11073
11074 std::task::Poll::Ready(Some(match header.ordinal {
11075 0x782319d6ce7fa05 => {
11076 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11077 let mut req = fidl::new_empty!(
11078 fidl::encoding::EmptyPayload,
11079 fidl::encoding::DefaultFuchsiaResourceDialect
11080 );
11081 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11082 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11083 Ok(SecureMemRequest::GetPhysicalSecureHeaps {
11084 responder: SecureMemGetPhysicalSecureHeapsResponder {
11085 control_handle: std::mem::ManuallyDrop::new(control_handle),
11086 tx_id: header.tx_id,
11087 },
11088 })
11089 }
11090 0x26404e23f1271214 => {
11091 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11092 let mut req = fidl::new_empty!(
11093 SecureMemGetPhysicalSecureHeapPropertiesRequest,
11094 fidl::encoding::DefaultFuchsiaResourceDialect
11095 );
11096 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemGetPhysicalSecureHeapPropertiesRequest>(&header, _body_bytes, handles, &mut req)?;
11097 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11098 Ok(SecureMemRequest::GetPhysicalSecureHeapProperties {
11099 entire_heap: req.entire_heap,
11100
11101 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder {
11102 control_handle: std::mem::ManuallyDrop::new(control_handle),
11103 tx_id: header.tx_id,
11104 },
11105 })
11106 }
11107 0x1ca1abcee8a0b33e => {
11108 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11109 let mut req = fidl::new_empty!(
11110 SecureMemAddSecureHeapPhysicalRangeRequest,
11111 fidl::encoding::DefaultFuchsiaResourceDialect
11112 );
11113 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemAddSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11114 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11115 Ok(SecureMemRequest::AddSecureHeapPhysicalRange {
11116 heap_range: req.heap_range,
11117
11118 responder: SecureMemAddSecureHeapPhysicalRangeResponder {
11119 control_handle: std::mem::ManuallyDrop::new(control_handle),
11120 tx_id: header.tx_id,
11121 },
11122 })
11123 }
11124 0x728a953e56df92ee => {
11125 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11126 let mut req = fidl::new_empty!(
11127 SecureMemDeleteSecureHeapPhysicalRangeRequest,
11128 fidl::encoding::DefaultFuchsiaResourceDialect
11129 );
11130 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemDeleteSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11131 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11132 Ok(SecureMemRequest::DeleteSecureHeapPhysicalRange {
11133 heap_range: req.heap_range,
11134
11135 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder {
11136 control_handle: std::mem::ManuallyDrop::new(control_handle),
11137 tx_id: header.tx_id,
11138 },
11139 })
11140 }
11141 0x154fbfa3646a890d => {
11142 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11143 let mut req = fidl::new_empty!(
11144 SecureMemModifySecureHeapPhysicalRangeRequest,
11145 fidl::encoding::DefaultFuchsiaResourceDialect
11146 );
11147 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemModifySecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11148 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11149 Ok(SecureMemRequest::ModifySecureHeapPhysicalRange {
11150 range_modification: req.range_modification,
11151
11152 responder: SecureMemModifySecureHeapPhysicalRangeResponder {
11153 control_handle: std::mem::ManuallyDrop::new(control_handle),
11154 tx_id: header.tx_id,
11155 },
11156 })
11157 }
11158 0x7480f72bb5bc7e5b => {
11159 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11160 let mut req = fidl::new_empty!(
11161 SecureMemZeroSubRangeRequest,
11162 fidl::encoding::DefaultFuchsiaResourceDialect
11163 );
11164 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemZeroSubRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11165 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11166 Ok(SecureMemRequest::ZeroSubRange {
11167 is_covering_range_explicit: req.is_covering_range_explicit,
11168 heap_range: req.heap_range,
11169
11170 responder: SecureMemZeroSubRangeResponder {
11171 control_handle: std::mem::ManuallyDrop::new(control_handle),
11172 tx_id: header.tx_id,
11173 },
11174 })
11175 }
11176 _ => Err(fidl::Error::UnknownOrdinal {
11177 ordinal: header.ordinal,
11178 protocol_name:
11179 <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
11180 }),
11181 }))
11182 },
11183 )
11184 }
11185}
11186
11187/// SecureMem
11188///
11189/// The client is sysmem. The server is securemem driver.
11190///
11191/// TEE - Trusted Execution Environment.
11192///
11193/// REE - Rich Execution Environment.
11194///
11195/// Enables sysmem to call the securemem driver to get any secure heaps
11196/// configured via the TEE (or via the securemem driver), and set any physical
11197/// secure heaps configured via sysmem.
11198///
11199/// Presently, dynamically-allocated secure heaps are configured via sysmem, as
11200/// it starts quite early during boot and can successfully reserve contiguous
11201/// physical memory. Presently, fixed-location secure heaps are configured via
11202/// TEE, as the plumbing goes from the bootloader to the TEE. However, this
11203/// protocol intentionally doesn't care which heaps are dynamically-allocated
11204/// and which are fixed-location.
11205#[derive(Debug)]
11206pub enum SecureMemRequest {
11207 /// Gets the physical address and length of any secure heap whose physical
11208 /// range is configured via the TEE.
11209 ///
11210 /// Presently, these will be fixed physical addresses and lengths, with the
11211 /// location plumbed via the TEE.
11212 ///
11213 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
11214 /// when there isn't any special heap-specific per-VMO setup or teardown
11215 /// required.
11216 ///
11217 /// The physical range must be secured/protected by the TEE before the
11218 /// securemem driver responds to this request with success.
11219 ///
11220 /// Sysmem should only call this once. Returning zero heaps is not a
11221 /// failure.
11222 ///
11223 /// Errors:
11224 /// * ZX_ERR_BAD_STATE - called more than once.
11225 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11226 /// with TEE which doesn't generate zx_status_t errors).
11227 /// * other errors are allowed; any other errors should be treated the same
11228 /// as ZX_ERR_INTERNAL.
11229 GetPhysicalSecureHeaps { responder: SecureMemGetPhysicalSecureHeapsResponder },
11230 /// This request from sysmem to the securemem driver gets the properties of
11231 /// a protected/secure heap.
11232 ///
11233 /// This only handles heaps with a single contiguous physical extent.
11234 ///
11235 /// The heap's entire physical range is indicated in case this request needs
11236 /// some physical space to auto-detect how many ranges are REE-usable. Any
11237 /// temporary HW protection ranges will be deleted before this request
11238 /// completes.
11239 GetPhysicalSecureHeapProperties {
11240 entire_heap: SecureHeapAndRange,
11241 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder,
11242 },
11243 /// This request from sysmem to the securemem driver conveys a physical
11244 /// range to add, for a heap whose physical range(s) are set up via
11245 /// sysmem.
11246 ///
11247 /// Only sysmem can call this because only sysmem is handed the client end
11248 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11249 /// securemem driver is the server end of this protocol.
11250 ///
11251 /// The securemem driver must configure all the covered offsets as protected
11252 /// before responding to this message with success.
11253 ///
11254 /// On failure, the securemem driver must ensure the protected range was not
11255 /// created.
11256 ///
11257 /// Sysmem must only call this up to once if dynamic_protection_ranges
11258 /// false.
11259 ///
11260 /// If dynamic_protection_ranges is true, sysmem can call this multiple
11261 /// times as long as the current number of ranges never exceeds
11262 /// max_protected_range_count.
11263 ///
11264 /// The caller must not attempt to add a range that matches an
11265 /// already-existing range. Added ranges can overlap each other as long as
11266 /// no two ranges match exactly.
11267 ///
11268 /// Errors:
11269 /// * ZX_ERR_BAD_STATE - called more than once when
11270 /// !dynamic_protection_ranges. Adding a heap that would cause overall
11271 /// heap count to exceed max_protected_range_count.
11272 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
11273 /// to protected_range_granularity.
11274 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11275 /// with TEE which doesn't generate zx_status_t errors).
11276 /// * other errors are possible, such as from communication failures or
11277 /// server propagation of zx_status_t failures.
11278 AddSecureHeapPhysicalRange {
11279 heap_range: SecureHeapAndRange,
11280 responder: SecureMemAddSecureHeapPhysicalRangeResponder,
11281 },
11282 /// This request from sysmem to the securemem driver conveys a physical
11283 /// range to delete, for a heap whose physical range(s) are set up via
11284 /// sysmem.
11285 ///
11286 /// Only sysmem can call this because only sysmem is handed the client end
11287 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11288 /// securemem driver is the server end of this protocol.
11289 ///
11290 /// The securemem driver must configure all the covered offsets as not
11291 /// protected before responding to this message with success.
11292 ///
11293 /// On failure, the securemem driver must ensure the protected range was not
11294 /// deleted.
11295 ///
11296 /// Sysmem must not call this if dynamic_protection_ranges false.
11297 ///
11298 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
11299 /// on various ranges that exist at the time of the call.
11300 ///
11301 /// If any portion of the range being deleted is not also covered by another
11302 /// protected range, then any ongoing DMA to any part of the entire range
11303 /// may be interrupted / may fail, potentially in a way that's disruptive to
11304 /// the entire system (bus lockup or similar, depending on device details).
11305 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
11306 /// any portion of the range being deleted, unless the caller has other
11307 /// active ranges covering every block of the range being deleted. Ongoing
11308 /// DMA to/from blocks outside the range being deleted is never impacted by
11309 /// the deletion.
11310 ///
11311 /// Errors:
11312 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
11313 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
11314 /// to protected_range_granularity.
11315 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11316 /// with TEE which doesn't generate zx_status_t errors).
11317 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
11318 /// * other errors are possible, such as from communication failures or
11319 /// server propagation of zx_status_t failures.
11320 DeleteSecureHeapPhysicalRange {
11321 heap_range: SecureHeapAndRange,
11322 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder,
11323 },
11324 /// This request from sysmem to the securemem driver conveys a physical
11325 /// range to modify and its new base and length, for a heap whose physical
11326 /// range(s) are set up via sysmem.
11327 ///
11328 /// Only sysmem can call this because only sysmem is handed the client end
11329 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11330 /// securemem driver is the server end of this protocol.
11331 ///
11332 /// The securemem driver must configure the range to cover only the new
11333 /// offsets before responding to this message with success.
11334 ///
11335 /// On failure, the securemem driver must ensure the range was not changed.
11336 ///
11337 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
11338 /// must not call this if !is_mod_protected_range_available.
11339 ///
11340 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
11341 /// on various ranges that exist at the time of the call.
11342 ///
11343 /// The range must only be modified at one end or the other, but not both.
11344 /// If the range is getting shorter, and the un-covered blocks are not
11345 /// covered by other active ranges, any ongoing DMA to the entire range
11346 /// that's geting shorter may fail in a way that disrupts the entire system
11347 /// (bus lockup or similar), so the caller must ensure that no DMA is
11348 /// ongoing to any portion of a range that is getting shorter, unless the
11349 /// blocks being un-covered by the modification to this range are all
11350 /// covered by other active ranges, in which case no disruption to ongoing
11351 /// DMA will occur.
11352 ///
11353 /// If a range is modified to become <= zero length, the range is deleted.
11354 ///
11355 /// Errors:
11356 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
11357 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
11358 /// that doesn't conform to protected_range_granularity, or old_range
11359 /// and new_range differ in both begin and end (disallowed).
11360 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11361 /// with TEE which doesn't generate zx_status_t errors).
11362 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
11363 /// * other errors are possible, such as from communication failures or
11364 /// server propagation of zx_status_t failures.
11365 ModifySecureHeapPhysicalRange {
11366 range_modification: SecureHeapAndRangeModification,
11367 responder: SecureMemModifySecureHeapPhysicalRangeResponder,
11368 },
11369 /// Zero a sub-range of a currently-existing physical range added via
11370 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
11371 /// exactly one physical range, and must not overlap with any other
11372 /// physical range.
11373 ///
11374 /// is_covering_range_explicit - When true, the covering range must be one
11375 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
11376 /// possibly modified since. When false, the covering range must not
11377 /// be one of the ranges explicitly created via
11378 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
11379 /// a covering range not created via AddSecureHeapPhysicalRange(). The
11380 /// covering range is typically the entire physical range (or a range
11381 /// which covers even more) of a heap configured by the TEE and whose
11382 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
11383 ///
11384 /// Ongoing DMA is not disrupted by this request.
11385 ZeroSubRange {
11386 is_covering_range_explicit: bool,
11387 heap_range: SecureHeapAndRange,
11388 responder: SecureMemZeroSubRangeResponder,
11389 },
11390}
11391
11392impl SecureMemRequest {
11393 #[allow(irrefutable_let_patterns)]
11394 pub fn into_get_physical_secure_heaps(
11395 self,
11396 ) -> Option<(SecureMemGetPhysicalSecureHeapsResponder)> {
11397 if let SecureMemRequest::GetPhysicalSecureHeaps { responder } = self {
11398 Some((responder))
11399 } else {
11400 None
11401 }
11402 }
11403
11404 #[allow(irrefutable_let_patterns)]
11405 pub fn into_get_physical_secure_heap_properties(
11406 self,
11407 ) -> Option<(SecureHeapAndRange, SecureMemGetPhysicalSecureHeapPropertiesResponder)> {
11408 if let SecureMemRequest::GetPhysicalSecureHeapProperties { entire_heap, responder } = self {
11409 Some((entire_heap, responder))
11410 } else {
11411 None
11412 }
11413 }
11414
11415 #[allow(irrefutable_let_patterns)]
11416 pub fn into_add_secure_heap_physical_range(
11417 self,
11418 ) -> Option<(SecureHeapAndRange, SecureMemAddSecureHeapPhysicalRangeResponder)> {
11419 if let SecureMemRequest::AddSecureHeapPhysicalRange { heap_range, responder } = self {
11420 Some((heap_range, responder))
11421 } else {
11422 None
11423 }
11424 }
11425
11426 #[allow(irrefutable_let_patterns)]
11427 pub fn into_delete_secure_heap_physical_range(
11428 self,
11429 ) -> Option<(SecureHeapAndRange, SecureMemDeleteSecureHeapPhysicalRangeResponder)> {
11430 if let SecureMemRequest::DeleteSecureHeapPhysicalRange { heap_range, responder } = self {
11431 Some((heap_range, responder))
11432 } else {
11433 None
11434 }
11435 }
11436
11437 #[allow(irrefutable_let_patterns)]
11438 pub fn into_modify_secure_heap_physical_range(
11439 self,
11440 ) -> Option<(SecureHeapAndRangeModification, SecureMemModifySecureHeapPhysicalRangeResponder)>
11441 {
11442 if let SecureMemRequest::ModifySecureHeapPhysicalRange { range_modification, responder } =
11443 self
11444 {
11445 Some((range_modification, responder))
11446 } else {
11447 None
11448 }
11449 }
11450
11451 #[allow(irrefutable_let_patterns)]
11452 pub fn into_zero_sub_range(
11453 self,
11454 ) -> Option<(bool, SecureHeapAndRange, SecureMemZeroSubRangeResponder)> {
11455 if let SecureMemRequest::ZeroSubRange {
11456 is_covering_range_explicit,
11457 heap_range,
11458 responder,
11459 } = self
11460 {
11461 Some((is_covering_range_explicit, heap_range, responder))
11462 } else {
11463 None
11464 }
11465 }
11466
11467 /// Name of the method defined in FIDL
11468 pub fn method_name(&self) -> &'static str {
11469 match *self {
11470 SecureMemRequest::GetPhysicalSecureHeaps { .. } => "get_physical_secure_heaps",
11471 SecureMemRequest::GetPhysicalSecureHeapProperties { .. } => {
11472 "get_physical_secure_heap_properties"
11473 }
11474 SecureMemRequest::AddSecureHeapPhysicalRange { .. } => "add_secure_heap_physical_range",
11475 SecureMemRequest::DeleteSecureHeapPhysicalRange { .. } => {
11476 "delete_secure_heap_physical_range"
11477 }
11478 SecureMemRequest::ModifySecureHeapPhysicalRange { .. } => {
11479 "modify_secure_heap_physical_range"
11480 }
11481 SecureMemRequest::ZeroSubRange { .. } => "zero_sub_range",
11482 }
11483 }
11484}
11485
11486#[derive(Debug, Clone)]
11487pub struct SecureMemControlHandle {
11488 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11489}
11490
11491impl fidl::endpoints::ControlHandle for SecureMemControlHandle {
11492 fn shutdown(&self) {
11493 self.inner.shutdown()
11494 }
11495
11496 fn shutdown_with_epitaph(&self, status: zx_status::Status) {
11497 self.inner.shutdown_with_epitaph(status)
11498 }
11499
11500 fn is_closed(&self) -> bool {
11501 self.inner.channel().is_closed()
11502 }
11503 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
11504 self.inner.channel().on_closed()
11505 }
11506
11507 #[cfg(target_os = "fuchsia")]
11508 fn signal_peer(
11509 &self,
11510 clear_mask: zx::Signals,
11511 set_mask: zx::Signals,
11512 ) -> Result<(), zx_status::Status> {
11513 use fidl::Peered;
11514 self.inner.channel().signal_peer(clear_mask, set_mask)
11515 }
11516}
11517
11518impl SecureMemControlHandle {}
11519
11520#[must_use = "FIDL methods require a response to be sent"]
11521#[derive(Debug)]
11522pub struct SecureMemGetPhysicalSecureHeapsResponder {
11523 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11524 tx_id: u32,
11525}
11526
11527/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11528/// if the responder is dropped without sending a response, so that the client
11529/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11530impl std::ops::Drop for SecureMemGetPhysicalSecureHeapsResponder {
11531 fn drop(&mut self) {
11532 self.control_handle.shutdown();
11533 // Safety: drops once, never accessed again
11534 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11535 }
11536}
11537
11538impl fidl::endpoints::Responder for SecureMemGetPhysicalSecureHeapsResponder {
11539 type ControlHandle = SecureMemControlHandle;
11540
11541 fn control_handle(&self) -> &SecureMemControlHandle {
11542 &self.control_handle
11543 }
11544
11545 fn drop_without_shutdown(mut self) {
11546 // Safety: drops once, never accessed again due to mem::forget
11547 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11548 // Prevent Drop from running (which would shut down the channel)
11549 std::mem::forget(self);
11550 }
11551}
11552
11553impl SecureMemGetPhysicalSecureHeapsResponder {
11554 /// Sends a response to the FIDL transaction.
11555 ///
11556 /// Sets the channel to shutdown if an error occurs.
11557 pub fn send(self, mut result: Result<&SecureHeapsAndRanges, i32>) -> Result<(), fidl::Error> {
11558 let _result = self.send_raw(result);
11559 if _result.is_err() {
11560 self.control_handle.shutdown();
11561 }
11562 self.drop_without_shutdown();
11563 _result
11564 }
11565
11566 /// Similar to "send" but does not shutdown the channel if an error occurs.
11567 pub fn send_no_shutdown_on_err(
11568 self,
11569 mut result: Result<&SecureHeapsAndRanges, i32>,
11570 ) -> Result<(), fidl::Error> {
11571 let _result = self.send_raw(result);
11572 self.drop_without_shutdown();
11573 _result
11574 }
11575
11576 fn send_raw(&self, mut result: Result<&SecureHeapsAndRanges, i32>) -> Result<(), fidl::Error> {
11577 self.control_handle.inner.send::<fidl::encoding::ResultType<
11578 SecureMemGetPhysicalSecureHeapsResponse,
11579 i32,
11580 >>(
11581 result.map(|heaps| (heaps,)),
11582 self.tx_id,
11583 0x782319d6ce7fa05,
11584 fidl::encoding::DynamicFlags::empty(),
11585 )
11586 }
11587}
11588
11589#[must_use = "FIDL methods require a response to be sent"]
11590#[derive(Debug)]
11591pub struct SecureMemGetPhysicalSecureHeapPropertiesResponder {
11592 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11593 tx_id: u32,
11594}
11595
11596/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11597/// if the responder is dropped without sending a response, so that the client
11598/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11599impl std::ops::Drop for SecureMemGetPhysicalSecureHeapPropertiesResponder {
11600 fn drop(&mut self) {
11601 self.control_handle.shutdown();
11602 // Safety: drops once, never accessed again
11603 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11604 }
11605}
11606
11607impl fidl::endpoints::Responder for SecureMemGetPhysicalSecureHeapPropertiesResponder {
11608 type ControlHandle = SecureMemControlHandle;
11609
11610 fn control_handle(&self) -> &SecureMemControlHandle {
11611 &self.control_handle
11612 }
11613
11614 fn drop_without_shutdown(mut self) {
11615 // Safety: drops once, never accessed again due to mem::forget
11616 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11617 // Prevent Drop from running (which would shut down the channel)
11618 std::mem::forget(self);
11619 }
11620}
11621
11622impl SecureMemGetPhysicalSecureHeapPropertiesResponder {
11623 /// Sends a response to the FIDL transaction.
11624 ///
11625 /// Sets the channel to shutdown if an error occurs.
11626 pub fn send(self, mut result: Result<&SecureHeapProperties, i32>) -> Result<(), fidl::Error> {
11627 let _result = self.send_raw(result);
11628 if _result.is_err() {
11629 self.control_handle.shutdown();
11630 }
11631 self.drop_without_shutdown();
11632 _result
11633 }
11634
11635 /// Similar to "send" but does not shutdown the channel if an error occurs.
11636 pub fn send_no_shutdown_on_err(
11637 self,
11638 mut result: Result<&SecureHeapProperties, i32>,
11639 ) -> Result<(), fidl::Error> {
11640 let _result = self.send_raw(result);
11641 self.drop_without_shutdown();
11642 _result
11643 }
11644
11645 fn send_raw(&self, mut result: Result<&SecureHeapProperties, i32>) -> Result<(), fidl::Error> {
11646 self.control_handle.inner.send::<fidl::encoding::ResultType<
11647 SecureMemGetPhysicalSecureHeapPropertiesResponse,
11648 i32,
11649 >>(
11650 result.map(|properties| (properties,)),
11651 self.tx_id,
11652 0x26404e23f1271214,
11653 fidl::encoding::DynamicFlags::empty(),
11654 )
11655 }
11656}
11657
11658#[must_use = "FIDL methods require a response to be sent"]
11659#[derive(Debug)]
11660pub struct SecureMemAddSecureHeapPhysicalRangeResponder {
11661 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11662 tx_id: u32,
11663}
11664
11665/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11666/// if the responder is dropped without sending a response, so that the client
11667/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11668impl std::ops::Drop for SecureMemAddSecureHeapPhysicalRangeResponder {
11669 fn drop(&mut self) {
11670 self.control_handle.shutdown();
11671 // Safety: drops once, never accessed again
11672 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11673 }
11674}
11675
11676impl fidl::endpoints::Responder for SecureMemAddSecureHeapPhysicalRangeResponder {
11677 type ControlHandle = SecureMemControlHandle;
11678
11679 fn control_handle(&self) -> &SecureMemControlHandle {
11680 &self.control_handle
11681 }
11682
11683 fn drop_without_shutdown(mut self) {
11684 // Safety: drops once, never accessed again due to mem::forget
11685 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11686 // Prevent Drop from running (which would shut down the channel)
11687 std::mem::forget(self);
11688 }
11689}
11690
11691impl SecureMemAddSecureHeapPhysicalRangeResponder {
11692 /// Sends a response to the FIDL transaction.
11693 ///
11694 /// Sets the channel to shutdown if an error occurs.
11695 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11696 let _result = self.send_raw(result);
11697 if _result.is_err() {
11698 self.control_handle.shutdown();
11699 }
11700 self.drop_without_shutdown();
11701 _result
11702 }
11703
11704 /// Similar to "send" but does not shutdown the channel if an error occurs.
11705 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11706 let _result = self.send_raw(result);
11707 self.drop_without_shutdown();
11708 _result
11709 }
11710
11711 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11712 self.control_handle
11713 .inner
11714 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11715 result,
11716 self.tx_id,
11717 0x1ca1abcee8a0b33e,
11718 fidl::encoding::DynamicFlags::empty(),
11719 )
11720 }
11721}
11722
11723#[must_use = "FIDL methods require a response to be sent"]
11724#[derive(Debug)]
11725pub struct SecureMemDeleteSecureHeapPhysicalRangeResponder {
11726 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11727 tx_id: u32,
11728}
11729
11730/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11731/// if the responder is dropped without sending a response, so that the client
11732/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11733impl std::ops::Drop for SecureMemDeleteSecureHeapPhysicalRangeResponder {
11734 fn drop(&mut self) {
11735 self.control_handle.shutdown();
11736 // Safety: drops once, never accessed again
11737 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11738 }
11739}
11740
11741impl fidl::endpoints::Responder for SecureMemDeleteSecureHeapPhysicalRangeResponder {
11742 type ControlHandle = SecureMemControlHandle;
11743
11744 fn control_handle(&self) -> &SecureMemControlHandle {
11745 &self.control_handle
11746 }
11747
11748 fn drop_without_shutdown(mut self) {
11749 // Safety: drops once, never accessed again due to mem::forget
11750 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11751 // Prevent Drop from running (which would shut down the channel)
11752 std::mem::forget(self);
11753 }
11754}
11755
11756impl SecureMemDeleteSecureHeapPhysicalRangeResponder {
11757 /// Sends a response to the FIDL transaction.
11758 ///
11759 /// Sets the channel to shutdown if an error occurs.
11760 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11761 let _result = self.send_raw(result);
11762 if _result.is_err() {
11763 self.control_handle.shutdown();
11764 }
11765 self.drop_without_shutdown();
11766 _result
11767 }
11768
11769 /// Similar to "send" but does not shutdown the channel if an error occurs.
11770 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11771 let _result = self.send_raw(result);
11772 self.drop_without_shutdown();
11773 _result
11774 }
11775
11776 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11777 self.control_handle
11778 .inner
11779 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11780 result,
11781 self.tx_id,
11782 0x728a953e56df92ee,
11783 fidl::encoding::DynamicFlags::empty(),
11784 )
11785 }
11786}
11787
11788#[must_use = "FIDL methods require a response to be sent"]
11789#[derive(Debug)]
11790pub struct SecureMemModifySecureHeapPhysicalRangeResponder {
11791 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11792 tx_id: u32,
11793}
11794
11795/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11796/// if the responder is dropped without sending a response, so that the client
11797/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11798impl std::ops::Drop for SecureMemModifySecureHeapPhysicalRangeResponder {
11799 fn drop(&mut self) {
11800 self.control_handle.shutdown();
11801 // Safety: drops once, never accessed again
11802 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11803 }
11804}
11805
11806impl fidl::endpoints::Responder for SecureMemModifySecureHeapPhysicalRangeResponder {
11807 type ControlHandle = SecureMemControlHandle;
11808
11809 fn control_handle(&self) -> &SecureMemControlHandle {
11810 &self.control_handle
11811 }
11812
11813 fn drop_without_shutdown(mut self) {
11814 // Safety: drops once, never accessed again due to mem::forget
11815 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11816 // Prevent Drop from running (which would shut down the channel)
11817 std::mem::forget(self);
11818 }
11819}
11820
11821impl SecureMemModifySecureHeapPhysicalRangeResponder {
11822 /// Sends a response to the FIDL transaction.
11823 ///
11824 /// Sets the channel to shutdown if an error occurs.
11825 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11826 let _result = self.send_raw(result);
11827 if _result.is_err() {
11828 self.control_handle.shutdown();
11829 }
11830 self.drop_without_shutdown();
11831 _result
11832 }
11833
11834 /// Similar to "send" but does not shutdown the channel if an error occurs.
11835 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11836 let _result = self.send_raw(result);
11837 self.drop_without_shutdown();
11838 _result
11839 }
11840
11841 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11842 self.control_handle
11843 .inner
11844 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11845 result,
11846 self.tx_id,
11847 0x154fbfa3646a890d,
11848 fidl::encoding::DynamicFlags::empty(),
11849 )
11850 }
11851}
11852
11853#[must_use = "FIDL methods require a response to be sent"]
11854#[derive(Debug)]
11855pub struct SecureMemZeroSubRangeResponder {
11856 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11857 tx_id: u32,
11858}
11859
11860/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11861/// if the responder is dropped without sending a response, so that the client
11862/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11863impl std::ops::Drop for SecureMemZeroSubRangeResponder {
11864 fn drop(&mut self) {
11865 self.control_handle.shutdown();
11866 // Safety: drops once, never accessed again
11867 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11868 }
11869}
11870
11871impl fidl::endpoints::Responder for SecureMemZeroSubRangeResponder {
11872 type ControlHandle = SecureMemControlHandle;
11873
11874 fn control_handle(&self) -> &SecureMemControlHandle {
11875 &self.control_handle
11876 }
11877
11878 fn drop_without_shutdown(mut self) {
11879 // Safety: drops once, never accessed again due to mem::forget
11880 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11881 // Prevent Drop from running (which would shut down the channel)
11882 std::mem::forget(self);
11883 }
11884}
11885
11886impl SecureMemZeroSubRangeResponder {
11887 /// Sends a response to the FIDL transaction.
11888 ///
11889 /// Sets the channel to shutdown if an error occurs.
11890 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11891 let _result = self.send_raw(result);
11892 if _result.is_err() {
11893 self.control_handle.shutdown();
11894 }
11895 self.drop_without_shutdown();
11896 _result
11897 }
11898
11899 /// Similar to "send" but does not shutdown the channel if an error occurs.
11900 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11901 let _result = self.send_raw(result);
11902 self.drop_without_shutdown();
11903 _result
11904 }
11905
11906 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11907 self.control_handle
11908 .inner
11909 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11910 result,
11911 self.tx_id,
11912 0x7480f72bb5bc7e5b,
11913 fidl::encoding::DynamicFlags::empty(),
11914 )
11915 }
11916}
11917
11918mod internal {
11919 use super::*;
11920
11921 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateNonSharedCollectionRequest {
11922 type Borrowed<'a> = &'a mut Self;
11923 fn take_or_borrow<'a>(
11924 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
11925 ) -> Self::Borrowed<'a> {
11926 value
11927 }
11928 }
11929
11930 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateNonSharedCollectionRequest {
11931 type Owned = Self;
11932
11933 #[inline(always)]
11934 fn inline_align(_context: fidl::encoding::Context) -> usize {
11935 4
11936 }
11937
11938 #[inline(always)]
11939 fn inline_size(_context: fidl::encoding::Context) -> usize {
11940 4
11941 }
11942 }
11943
11944 unsafe impl
11945 fidl::encoding::Encode<
11946 AllocatorAllocateNonSharedCollectionRequest,
11947 fidl::encoding::DefaultFuchsiaResourceDialect,
11948 > for &mut AllocatorAllocateNonSharedCollectionRequest
11949 {
11950 #[inline]
11951 unsafe fn encode(
11952 self,
11953 encoder: &mut fidl::encoding::Encoder<
11954 '_,
11955 fidl::encoding::DefaultFuchsiaResourceDialect,
11956 >,
11957 offset: usize,
11958 _depth: fidl::encoding::Depth,
11959 ) -> fidl::Result<()> {
11960 encoder.debug_check_bounds::<AllocatorAllocateNonSharedCollectionRequest>(offset);
11961 // Delegate to tuple encoding.
11962 fidl::encoding::Encode::<AllocatorAllocateNonSharedCollectionRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
11963 (
11964 <fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.collection_request),
11965 ),
11966 encoder, offset, _depth
11967 )
11968 }
11969 }
11970 unsafe impl<
11971 T0: fidl::encoding::Encode<
11972 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
11973 fidl::encoding::DefaultFuchsiaResourceDialect,
11974 >,
11975 >
11976 fidl::encoding::Encode<
11977 AllocatorAllocateNonSharedCollectionRequest,
11978 fidl::encoding::DefaultFuchsiaResourceDialect,
11979 > for (T0,)
11980 {
11981 #[inline]
11982 unsafe fn encode(
11983 self,
11984 encoder: &mut fidl::encoding::Encoder<
11985 '_,
11986 fidl::encoding::DefaultFuchsiaResourceDialect,
11987 >,
11988 offset: usize,
11989 depth: fidl::encoding::Depth,
11990 ) -> fidl::Result<()> {
11991 encoder.debug_check_bounds::<AllocatorAllocateNonSharedCollectionRequest>(offset);
11992 // Zero out padding regions. There's no need to apply masks
11993 // because the unmasked parts will be overwritten by fields.
11994 // Write the fields.
11995 self.0.encode(encoder, offset + 0, depth)?;
11996 Ok(())
11997 }
11998 }
11999
12000 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12001 for AllocatorAllocateNonSharedCollectionRequest
12002 {
12003 #[inline(always)]
12004 fn new_empty() -> Self {
12005 Self {
12006 collection_request: fidl::new_empty!(
12007 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12008 fidl::encoding::DefaultFuchsiaResourceDialect
12009 ),
12010 }
12011 }
12012
12013 #[inline]
12014 unsafe fn decode(
12015 &mut self,
12016 decoder: &mut fidl::encoding::Decoder<
12017 '_,
12018 fidl::encoding::DefaultFuchsiaResourceDialect,
12019 >,
12020 offset: usize,
12021 _depth: fidl::encoding::Depth,
12022 ) -> fidl::Result<()> {
12023 decoder.debug_check_bounds::<Self>(offset);
12024 // Verify that padding bytes are zero.
12025 fidl::decode!(
12026 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12027 fidl::encoding::DefaultFuchsiaResourceDialect,
12028 &mut self.collection_request,
12029 decoder,
12030 offset + 0,
12031 _depth
12032 )?;
12033 Ok(())
12034 }
12035 }
12036
12037 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateSharedCollectionRequest {
12038 type Borrowed<'a> = &'a mut Self;
12039 fn take_or_borrow<'a>(
12040 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12041 ) -> Self::Borrowed<'a> {
12042 value
12043 }
12044 }
12045
12046 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateSharedCollectionRequest {
12047 type Owned = Self;
12048
12049 #[inline(always)]
12050 fn inline_align(_context: fidl::encoding::Context) -> usize {
12051 4
12052 }
12053
12054 #[inline(always)]
12055 fn inline_size(_context: fidl::encoding::Context) -> usize {
12056 4
12057 }
12058 }
12059
12060 unsafe impl
12061 fidl::encoding::Encode<
12062 AllocatorAllocateSharedCollectionRequest,
12063 fidl::encoding::DefaultFuchsiaResourceDialect,
12064 > for &mut AllocatorAllocateSharedCollectionRequest
12065 {
12066 #[inline]
12067 unsafe fn encode(
12068 self,
12069 encoder: &mut fidl::encoding::Encoder<
12070 '_,
12071 fidl::encoding::DefaultFuchsiaResourceDialect,
12072 >,
12073 offset: usize,
12074 _depth: fidl::encoding::Depth,
12075 ) -> fidl::Result<()> {
12076 encoder.debug_check_bounds::<AllocatorAllocateSharedCollectionRequest>(offset);
12077 // Delegate to tuple encoding.
12078 fidl::encoding::Encode::<
12079 AllocatorAllocateSharedCollectionRequest,
12080 fidl::encoding::DefaultFuchsiaResourceDialect,
12081 >::encode(
12082 (
12083 <fidl::encoding::Endpoint<
12084 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12085 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12086 &mut self.token_request,
12087 ),
12088 ),
12089 encoder,
12090 offset,
12091 _depth,
12092 )
12093 }
12094 }
12095 unsafe impl<
12096 T0: fidl::encoding::Encode<
12097 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12098 fidl::encoding::DefaultFuchsiaResourceDialect,
12099 >,
12100 >
12101 fidl::encoding::Encode<
12102 AllocatorAllocateSharedCollectionRequest,
12103 fidl::encoding::DefaultFuchsiaResourceDialect,
12104 > for (T0,)
12105 {
12106 #[inline]
12107 unsafe fn encode(
12108 self,
12109 encoder: &mut fidl::encoding::Encoder<
12110 '_,
12111 fidl::encoding::DefaultFuchsiaResourceDialect,
12112 >,
12113 offset: usize,
12114 depth: fidl::encoding::Depth,
12115 ) -> fidl::Result<()> {
12116 encoder.debug_check_bounds::<AllocatorAllocateSharedCollectionRequest>(offset);
12117 // Zero out padding regions. There's no need to apply masks
12118 // because the unmasked parts will be overwritten by fields.
12119 // Write the fields.
12120 self.0.encode(encoder, offset + 0, depth)?;
12121 Ok(())
12122 }
12123 }
12124
12125 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12126 for AllocatorAllocateSharedCollectionRequest
12127 {
12128 #[inline(always)]
12129 fn new_empty() -> Self {
12130 Self {
12131 token_request: fidl::new_empty!(
12132 fidl::encoding::Endpoint<
12133 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12134 >,
12135 fidl::encoding::DefaultFuchsiaResourceDialect
12136 ),
12137 }
12138 }
12139
12140 #[inline]
12141 unsafe fn decode(
12142 &mut self,
12143 decoder: &mut fidl::encoding::Decoder<
12144 '_,
12145 fidl::encoding::DefaultFuchsiaResourceDialect,
12146 >,
12147 offset: usize,
12148 _depth: fidl::encoding::Depth,
12149 ) -> fidl::Result<()> {
12150 decoder.debug_check_bounds::<Self>(offset);
12151 // Verify that padding bytes are zero.
12152 fidl::decode!(
12153 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12154 fidl::encoding::DefaultFuchsiaResourceDialect,
12155 &mut self.token_request,
12156 decoder,
12157 offset + 0,
12158 _depth
12159 )?;
12160 Ok(())
12161 }
12162 }
12163
12164 impl fidl::encoding::ResourceTypeMarker for AllocatorBindSharedCollectionRequest {
12165 type Borrowed<'a> = &'a mut Self;
12166 fn take_or_borrow<'a>(
12167 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12168 ) -> Self::Borrowed<'a> {
12169 value
12170 }
12171 }
12172
12173 unsafe impl fidl::encoding::TypeMarker for AllocatorBindSharedCollectionRequest {
12174 type Owned = Self;
12175
12176 #[inline(always)]
12177 fn inline_align(_context: fidl::encoding::Context) -> usize {
12178 4
12179 }
12180
12181 #[inline(always)]
12182 fn inline_size(_context: fidl::encoding::Context) -> usize {
12183 8
12184 }
12185 }
12186
12187 unsafe impl
12188 fidl::encoding::Encode<
12189 AllocatorBindSharedCollectionRequest,
12190 fidl::encoding::DefaultFuchsiaResourceDialect,
12191 > for &mut AllocatorBindSharedCollectionRequest
12192 {
12193 #[inline]
12194 unsafe fn encode(
12195 self,
12196 encoder: &mut fidl::encoding::Encoder<
12197 '_,
12198 fidl::encoding::DefaultFuchsiaResourceDialect,
12199 >,
12200 offset: usize,
12201 _depth: fidl::encoding::Depth,
12202 ) -> fidl::Result<()> {
12203 encoder.debug_check_bounds::<AllocatorBindSharedCollectionRequest>(offset);
12204 // Delegate to tuple encoding.
12205 fidl::encoding::Encode::<AllocatorBindSharedCollectionRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
12206 (
12207 <fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.token),
12208 <fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffer_collection_request),
12209 ),
12210 encoder, offset, _depth
12211 )
12212 }
12213 }
12214 unsafe impl<
12215 T0: fidl::encoding::Encode<
12216 fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
12217 fidl::encoding::DefaultFuchsiaResourceDialect,
12218 >,
12219 T1: fidl::encoding::Encode<
12220 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12221 fidl::encoding::DefaultFuchsiaResourceDialect,
12222 >,
12223 >
12224 fidl::encoding::Encode<
12225 AllocatorBindSharedCollectionRequest,
12226 fidl::encoding::DefaultFuchsiaResourceDialect,
12227 > for (T0, T1)
12228 {
12229 #[inline]
12230 unsafe fn encode(
12231 self,
12232 encoder: &mut fidl::encoding::Encoder<
12233 '_,
12234 fidl::encoding::DefaultFuchsiaResourceDialect,
12235 >,
12236 offset: usize,
12237 depth: fidl::encoding::Depth,
12238 ) -> fidl::Result<()> {
12239 encoder.debug_check_bounds::<AllocatorBindSharedCollectionRequest>(offset);
12240 // Zero out padding regions. There's no need to apply masks
12241 // because the unmasked parts will be overwritten by fields.
12242 // Write the fields.
12243 self.0.encode(encoder, offset + 0, depth)?;
12244 self.1.encode(encoder, offset + 4, depth)?;
12245 Ok(())
12246 }
12247 }
12248
12249 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12250 for AllocatorBindSharedCollectionRequest
12251 {
12252 #[inline(always)]
12253 fn new_empty() -> Self {
12254 Self {
12255 token: fidl::new_empty!(
12256 fidl::encoding::Endpoint<
12257 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
12258 >,
12259 fidl::encoding::DefaultFuchsiaResourceDialect
12260 ),
12261 buffer_collection_request: fidl::new_empty!(
12262 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12263 fidl::encoding::DefaultFuchsiaResourceDialect
12264 ),
12265 }
12266 }
12267
12268 #[inline]
12269 unsafe fn decode(
12270 &mut self,
12271 decoder: &mut fidl::encoding::Decoder<
12272 '_,
12273 fidl::encoding::DefaultFuchsiaResourceDialect,
12274 >,
12275 offset: usize,
12276 _depth: fidl::encoding::Depth,
12277 ) -> fidl::Result<()> {
12278 decoder.debug_check_bounds::<Self>(offset);
12279 // Verify that padding bytes are zero.
12280 fidl::decode!(
12281 fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
12282 fidl::encoding::DefaultFuchsiaResourceDialect,
12283 &mut self.token,
12284 decoder,
12285 offset + 0,
12286 _depth
12287 )?;
12288 fidl::decode!(
12289 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12290 fidl::encoding::DefaultFuchsiaResourceDialect,
12291 &mut self.buffer_collection_request,
12292 decoder,
12293 offset + 4,
12294 _depth
12295 )?;
12296 Ok(())
12297 }
12298 }
12299
12300 impl fidl::encoding::ResourceTypeMarker for AllocatorConnectToSysmem2AllocatorRequest {
12301 type Borrowed<'a> = &'a mut Self;
12302 fn take_or_borrow<'a>(
12303 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12304 ) -> Self::Borrowed<'a> {
12305 value
12306 }
12307 }
12308
12309 unsafe impl fidl::encoding::TypeMarker for AllocatorConnectToSysmem2AllocatorRequest {
12310 type Owned = Self;
12311
12312 #[inline(always)]
12313 fn inline_align(_context: fidl::encoding::Context) -> usize {
12314 4
12315 }
12316
12317 #[inline(always)]
12318 fn inline_size(_context: fidl::encoding::Context) -> usize {
12319 4
12320 }
12321 }
12322
12323 unsafe impl
12324 fidl::encoding::Encode<
12325 AllocatorConnectToSysmem2AllocatorRequest,
12326 fidl::encoding::DefaultFuchsiaResourceDialect,
12327 > for &mut AllocatorConnectToSysmem2AllocatorRequest
12328 {
12329 #[inline]
12330 unsafe fn encode(
12331 self,
12332 encoder: &mut fidl::encoding::Encoder<
12333 '_,
12334 fidl::encoding::DefaultFuchsiaResourceDialect,
12335 >,
12336 offset: usize,
12337 _depth: fidl::encoding::Depth,
12338 ) -> fidl::Result<()> {
12339 encoder.debug_check_bounds::<AllocatorConnectToSysmem2AllocatorRequest>(offset);
12340 // Delegate to tuple encoding.
12341 fidl::encoding::Encode::<
12342 AllocatorConnectToSysmem2AllocatorRequest,
12343 fidl::encoding::DefaultFuchsiaResourceDialect,
12344 >::encode(
12345 (<fidl::encoding::Endpoint<
12346 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12347 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12348 &mut self.allocator_request,
12349 ),),
12350 encoder,
12351 offset,
12352 _depth,
12353 )
12354 }
12355 }
12356 unsafe impl<
12357 T0: fidl::encoding::Encode<
12358 fidl::encoding::Endpoint<
12359 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12360 >,
12361 fidl::encoding::DefaultFuchsiaResourceDialect,
12362 >,
12363 >
12364 fidl::encoding::Encode<
12365 AllocatorConnectToSysmem2AllocatorRequest,
12366 fidl::encoding::DefaultFuchsiaResourceDialect,
12367 > for (T0,)
12368 {
12369 #[inline]
12370 unsafe fn encode(
12371 self,
12372 encoder: &mut fidl::encoding::Encoder<
12373 '_,
12374 fidl::encoding::DefaultFuchsiaResourceDialect,
12375 >,
12376 offset: usize,
12377 depth: fidl::encoding::Depth,
12378 ) -> fidl::Result<()> {
12379 encoder.debug_check_bounds::<AllocatorConnectToSysmem2AllocatorRequest>(offset);
12380 // Zero out padding regions. There's no need to apply masks
12381 // because the unmasked parts will be overwritten by fields.
12382 // Write the fields.
12383 self.0.encode(encoder, offset + 0, depth)?;
12384 Ok(())
12385 }
12386 }
12387
12388 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12389 for AllocatorConnectToSysmem2AllocatorRequest
12390 {
12391 #[inline(always)]
12392 fn new_empty() -> Self {
12393 Self {
12394 allocator_request: fidl::new_empty!(
12395 fidl::encoding::Endpoint<
12396 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12397 >,
12398 fidl::encoding::DefaultFuchsiaResourceDialect
12399 ),
12400 }
12401 }
12402
12403 #[inline]
12404 unsafe fn decode(
12405 &mut self,
12406 decoder: &mut fidl::encoding::Decoder<
12407 '_,
12408 fidl::encoding::DefaultFuchsiaResourceDialect,
12409 >,
12410 offset: usize,
12411 _depth: fidl::encoding::Depth,
12412 ) -> fidl::Result<()> {
12413 decoder.debug_check_bounds::<Self>(offset);
12414 // Verify that padding bytes are zero.
12415 fidl::decode!(
12416 fidl::encoding::Endpoint<
12417 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12418 >,
12419 fidl::encoding::DefaultFuchsiaResourceDialect,
12420 &mut self.allocator_request,
12421 decoder,
12422 offset + 0,
12423 _depth
12424 )?;
12425 Ok(())
12426 }
12427 }
12428
12429 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
12430 type Borrowed<'a> = &'a mut Self;
12431 fn take_or_borrow<'a>(
12432 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12433 ) -> Self::Borrowed<'a> {
12434 value
12435 }
12436 }
12437
12438 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
12439 type Owned = Self;
12440
12441 #[inline(always)]
12442 fn inline_align(_context: fidl::encoding::Context) -> usize {
12443 4
12444 }
12445
12446 #[inline(always)]
12447 fn inline_size(_context: fidl::encoding::Context) -> usize {
12448 8
12449 }
12450 }
12451
12452 unsafe impl
12453 fidl::encoding::Encode<
12454 BufferCollectionAttachLifetimeTrackingRequest,
12455 fidl::encoding::DefaultFuchsiaResourceDialect,
12456 > for &mut BufferCollectionAttachLifetimeTrackingRequest
12457 {
12458 #[inline]
12459 unsafe fn encode(
12460 self,
12461 encoder: &mut fidl::encoding::Encoder<
12462 '_,
12463 fidl::encoding::DefaultFuchsiaResourceDialect,
12464 >,
12465 offset: usize,
12466 _depth: fidl::encoding::Depth,
12467 ) -> fidl::Result<()> {
12468 encoder.debug_check_bounds::<BufferCollectionAttachLifetimeTrackingRequest>(offset);
12469 // Delegate to tuple encoding.
12470 fidl::encoding::Encode::<
12471 BufferCollectionAttachLifetimeTrackingRequest,
12472 fidl::encoding::DefaultFuchsiaResourceDialect,
12473 >::encode(
12474 (
12475 <fidl::encoding::HandleType<
12476 fidl::EventPair,
12477 { fidl::ObjectType::EVENTPAIR.into_raw() },
12478 2147483648,
12479 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12480 &mut self.server_end
12481 ),
12482 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffers_remaining),
12483 ),
12484 encoder,
12485 offset,
12486 _depth,
12487 )
12488 }
12489 }
12490 unsafe impl<
12491 T0: fidl::encoding::Encode<
12492 fidl::encoding::HandleType<
12493 fidl::EventPair,
12494 { fidl::ObjectType::EVENTPAIR.into_raw() },
12495 2147483648,
12496 >,
12497 fidl::encoding::DefaultFuchsiaResourceDialect,
12498 >,
12499 T1: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12500 >
12501 fidl::encoding::Encode<
12502 BufferCollectionAttachLifetimeTrackingRequest,
12503 fidl::encoding::DefaultFuchsiaResourceDialect,
12504 > for (T0, T1)
12505 {
12506 #[inline]
12507 unsafe fn encode(
12508 self,
12509 encoder: &mut fidl::encoding::Encoder<
12510 '_,
12511 fidl::encoding::DefaultFuchsiaResourceDialect,
12512 >,
12513 offset: usize,
12514 depth: fidl::encoding::Depth,
12515 ) -> fidl::Result<()> {
12516 encoder.debug_check_bounds::<BufferCollectionAttachLifetimeTrackingRequest>(offset);
12517 // Zero out padding regions. There's no need to apply masks
12518 // because the unmasked parts will be overwritten by fields.
12519 // Write the fields.
12520 self.0.encode(encoder, offset + 0, depth)?;
12521 self.1.encode(encoder, offset + 4, depth)?;
12522 Ok(())
12523 }
12524 }
12525
12526 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12527 for BufferCollectionAttachLifetimeTrackingRequest
12528 {
12529 #[inline(always)]
12530 fn new_empty() -> Self {
12531 Self {
12532 server_end: fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
12533 buffers_remaining: fidl::new_empty!(
12534 u32,
12535 fidl::encoding::DefaultFuchsiaResourceDialect
12536 ),
12537 }
12538 }
12539
12540 #[inline]
12541 unsafe fn decode(
12542 &mut self,
12543 decoder: &mut fidl::encoding::Decoder<
12544 '_,
12545 fidl::encoding::DefaultFuchsiaResourceDialect,
12546 >,
12547 offset: usize,
12548 _depth: fidl::encoding::Depth,
12549 ) -> fidl::Result<()> {
12550 decoder.debug_check_bounds::<Self>(offset);
12551 // Verify that padding bytes are zero.
12552 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.server_end, decoder, offset + 0, _depth)?;
12553 fidl::decode!(
12554 u32,
12555 fidl::encoding::DefaultFuchsiaResourceDialect,
12556 &mut self.buffers_remaining,
12557 decoder,
12558 offset + 4,
12559 _depth
12560 )?;
12561 Ok(())
12562 }
12563 }
12564
12565 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachTokenRequest {
12566 type Borrowed<'a> = &'a mut Self;
12567 fn take_or_borrow<'a>(
12568 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12569 ) -> Self::Borrowed<'a> {
12570 value
12571 }
12572 }
12573
12574 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachTokenRequest {
12575 type Owned = Self;
12576
12577 #[inline(always)]
12578 fn inline_align(_context: fidl::encoding::Context) -> usize {
12579 4
12580 }
12581
12582 #[inline(always)]
12583 fn inline_size(_context: fidl::encoding::Context) -> usize {
12584 8
12585 }
12586 }
12587
12588 unsafe impl
12589 fidl::encoding::Encode<
12590 BufferCollectionAttachTokenRequest,
12591 fidl::encoding::DefaultFuchsiaResourceDialect,
12592 > for &mut BufferCollectionAttachTokenRequest
12593 {
12594 #[inline]
12595 unsafe fn encode(
12596 self,
12597 encoder: &mut fidl::encoding::Encoder<
12598 '_,
12599 fidl::encoding::DefaultFuchsiaResourceDialect,
12600 >,
12601 offset: usize,
12602 _depth: fidl::encoding::Depth,
12603 ) -> fidl::Result<()> {
12604 encoder.debug_check_bounds::<BufferCollectionAttachTokenRequest>(offset);
12605 // Delegate to tuple encoding.
12606 fidl::encoding::Encode::<
12607 BufferCollectionAttachTokenRequest,
12608 fidl::encoding::DefaultFuchsiaResourceDialect,
12609 >::encode(
12610 (
12611 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.rights_attenuation_mask),
12612 <fidl::encoding::Endpoint<
12613 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12614 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12615 &mut self.token_request,
12616 ),
12617 ),
12618 encoder,
12619 offset,
12620 _depth,
12621 )
12622 }
12623 }
12624 unsafe impl<
12625 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12626 T1: fidl::encoding::Encode<
12627 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12628 fidl::encoding::DefaultFuchsiaResourceDialect,
12629 >,
12630 >
12631 fidl::encoding::Encode<
12632 BufferCollectionAttachTokenRequest,
12633 fidl::encoding::DefaultFuchsiaResourceDialect,
12634 > for (T0, T1)
12635 {
12636 #[inline]
12637 unsafe fn encode(
12638 self,
12639 encoder: &mut fidl::encoding::Encoder<
12640 '_,
12641 fidl::encoding::DefaultFuchsiaResourceDialect,
12642 >,
12643 offset: usize,
12644 depth: fidl::encoding::Depth,
12645 ) -> fidl::Result<()> {
12646 encoder.debug_check_bounds::<BufferCollectionAttachTokenRequest>(offset);
12647 // Zero out padding regions. There's no need to apply masks
12648 // because the unmasked parts will be overwritten by fields.
12649 // Write the fields.
12650 self.0.encode(encoder, offset + 0, depth)?;
12651 self.1.encode(encoder, offset + 4, depth)?;
12652 Ok(())
12653 }
12654 }
12655
12656 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12657 for BufferCollectionAttachTokenRequest
12658 {
12659 #[inline(always)]
12660 fn new_empty() -> Self {
12661 Self {
12662 rights_attenuation_mask: fidl::new_empty!(
12663 u32,
12664 fidl::encoding::DefaultFuchsiaResourceDialect
12665 ),
12666 token_request: fidl::new_empty!(
12667 fidl::encoding::Endpoint<
12668 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12669 >,
12670 fidl::encoding::DefaultFuchsiaResourceDialect
12671 ),
12672 }
12673 }
12674
12675 #[inline]
12676 unsafe fn decode(
12677 &mut self,
12678 decoder: &mut fidl::encoding::Decoder<
12679 '_,
12680 fidl::encoding::DefaultFuchsiaResourceDialect,
12681 >,
12682 offset: usize,
12683 _depth: fidl::encoding::Depth,
12684 ) -> fidl::Result<()> {
12685 decoder.debug_check_bounds::<Self>(offset);
12686 // Verify that padding bytes are zero.
12687 fidl::decode!(
12688 u32,
12689 fidl::encoding::DefaultFuchsiaResourceDialect,
12690 &mut self.rights_attenuation_mask,
12691 decoder,
12692 offset + 0,
12693 _depth
12694 )?;
12695 fidl::decode!(
12696 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12697 fidl::encoding::DefaultFuchsiaResourceDialect,
12698 &mut self.token_request,
12699 decoder,
12700 offset + 4,
12701 _depth
12702 )?;
12703 Ok(())
12704 }
12705 }
12706
12707 impl fidl::encoding::ResourceTypeMarker for BufferCollectionInfo {
12708 type Borrowed<'a> = &'a mut Self;
12709 fn take_or_borrow<'a>(
12710 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12711 ) -> Self::Borrowed<'a> {
12712 value
12713 }
12714 }
12715
12716 unsafe impl fidl::encoding::TypeMarker for BufferCollectionInfo {
12717 type Owned = Self;
12718
12719 #[inline(always)]
12720 fn inline_align(_context: fidl::encoding::Context) -> usize {
12721 8
12722 }
12723
12724 #[inline(always)]
12725 fn inline_size(_context: fidl::encoding::Context) -> usize {
12726 352
12727 }
12728 }
12729
12730 unsafe impl
12731 fidl::encoding::Encode<BufferCollectionInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
12732 for &mut BufferCollectionInfo
12733 {
12734 #[inline]
12735 unsafe fn encode(
12736 self,
12737 encoder: &mut fidl::encoding::Encoder<
12738 '_,
12739 fidl::encoding::DefaultFuchsiaResourceDialect,
12740 >,
12741 offset: usize,
12742 _depth: fidl::encoding::Depth,
12743 ) -> fidl::Result<()> {
12744 encoder.debug_check_bounds::<BufferCollectionInfo>(offset);
12745 // Delegate to tuple encoding.
12746 fidl::encoding::Encode::<
12747 BufferCollectionInfo,
12748 fidl::encoding::DefaultFuchsiaResourceDialect,
12749 >::encode(
12750 (
12751 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffer_count),
12752 <BufferFormat as fidl::encoding::ValueTypeMarker>::borrow(&self.format),
12753 <fidl::encoding::Array<
12754 fidl::encoding::Optional<
12755 fidl::encoding::HandleType<
12756 fidl::Vmo,
12757 { fidl::ObjectType::VMO.into_raw() },
12758 2147483648,
12759 >,
12760 >,
12761 64,
12762 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12763 &mut self.vmos
12764 ),
12765 <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.vmo_size),
12766 ),
12767 encoder,
12768 offset,
12769 _depth,
12770 )
12771 }
12772 }
12773 unsafe impl<
12774 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12775 T1: fidl::encoding::Encode<BufferFormat, fidl::encoding::DefaultFuchsiaResourceDialect>,
12776 T2: fidl::encoding::Encode<
12777 fidl::encoding::Array<
12778 fidl::encoding::Optional<
12779 fidl::encoding::HandleType<
12780 fidl::Vmo,
12781 { fidl::ObjectType::VMO.into_raw() },
12782 2147483648,
12783 >,
12784 >,
12785 64,
12786 >,
12787 fidl::encoding::DefaultFuchsiaResourceDialect,
12788 >,
12789 T3: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
12790 >
12791 fidl::encoding::Encode<BufferCollectionInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
12792 for (T0, T1, T2, T3)
12793 {
12794 #[inline]
12795 unsafe fn encode(
12796 self,
12797 encoder: &mut fidl::encoding::Encoder<
12798 '_,
12799 fidl::encoding::DefaultFuchsiaResourceDialect,
12800 >,
12801 offset: usize,
12802 depth: fidl::encoding::Depth,
12803 ) -> fidl::Result<()> {
12804 encoder.debug_check_bounds::<BufferCollectionInfo>(offset);
12805 // Zero out padding regions. There's no need to apply masks
12806 // because the unmasked parts will be overwritten by fields.
12807 unsafe {
12808 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
12809 (ptr as *mut u64).write_unaligned(0);
12810 }
12811 // Write the fields.
12812 self.0.encode(encoder, offset + 0, depth)?;
12813 self.1.encode(encoder, offset + 8, depth)?;
12814 self.2.encode(encoder, offset + 88, depth)?;
12815 self.3.encode(encoder, offset + 344, depth)?;
12816 Ok(())
12817 }
12818 }
12819
12820 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12821 for BufferCollectionInfo
12822 {
12823 #[inline(always)]
12824 fn new_empty() -> Self {
12825 Self {
12826 buffer_count: fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect),
12827 format: fidl::new_empty!(
12828 BufferFormat,
12829 fidl::encoding::DefaultFuchsiaResourceDialect
12830 ),
12831 vmos: fidl::new_empty!(
12832 fidl::encoding::Array<
12833 fidl::encoding::Optional<
12834 fidl::encoding::HandleType<
12835 fidl::Vmo,
12836 { fidl::ObjectType::VMO.into_raw() },
12837 2147483648,
12838 >,
12839 >,
12840 64,
12841 >,
12842 fidl::encoding::DefaultFuchsiaResourceDialect
12843 ),
12844 vmo_size: fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect),
12845 }
12846 }
12847
12848 #[inline]
12849 unsafe fn decode(
12850 &mut self,
12851 decoder: &mut fidl::encoding::Decoder<
12852 '_,
12853 fidl::encoding::DefaultFuchsiaResourceDialect,
12854 >,
12855 offset: usize,
12856 _depth: fidl::encoding::Depth,
12857 ) -> fidl::Result<()> {
12858 decoder.debug_check_bounds::<Self>(offset);
12859 // Verify that padding bytes are zero.
12860 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
12861 let padval = unsafe { (ptr as *const u64).read_unaligned() };
12862 let mask = 0xffffffff00000000u64;
12863 let maskedval = padval & mask;
12864 if maskedval != 0 {
12865 return Err(fidl::Error::NonZeroPadding {
12866 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
12867 });
12868 }
12869 fidl::decode!(
12870 u32,
12871 fidl::encoding::DefaultFuchsiaResourceDialect,
12872 &mut self.buffer_count,
12873 decoder,
12874 offset + 0,
12875 _depth
12876 )?;
12877 fidl::decode!(
12878 BufferFormat,
12879 fidl::encoding::DefaultFuchsiaResourceDialect,
12880 &mut self.format,
12881 decoder,
12882 offset + 8,
12883 _depth
12884 )?;
12885 fidl::decode!(
12886 fidl::encoding::Array<
12887 fidl::encoding::Optional<
12888 fidl::encoding::HandleType<
12889 fidl::Vmo,
12890 { fidl::ObjectType::VMO.into_raw() },
12891 2147483648,
12892 >,
12893 >,
12894 64,
12895 >,
12896 fidl::encoding::DefaultFuchsiaResourceDialect,
12897 &mut self.vmos,
12898 decoder,
12899 offset + 88,
12900 _depth
12901 )?;
12902 fidl::decode!(
12903 u64,
12904 fidl::encoding::DefaultFuchsiaResourceDialect,
12905 &mut self.vmo_size,
12906 decoder,
12907 offset + 344,
12908 _depth
12909 )?;
12910 Ok(())
12911 }
12912 }
12913
12914 impl fidl::encoding::ResourceTypeMarker for BufferCollectionInfo2 {
12915 type Borrowed<'a> = &'a mut Self;
12916 fn take_or_borrow<'a>(
12917 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12918 ) -> Self::Borrowed<'a> {
12919 value
12920 }
12921 }
12922
12923 unsafe impl fidl::encoding::TypeMarker for BufferCollectionInfo2 {
12924 type Owned = Self;
12925
12926 #[inline(always)]
12927 fn inline_align(_context: fidl::encoding::Context) -> usize {
12928 8
12929 }
12930
12931 #[inline(always)]
12932 fn inline_size(_context: fidl::encoding::Context) -> usize {
12933 1296
12934 }
12935 }
12936
12937 unsafe impl
12938 fidl::encoding::Encode<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>
12939 for &mut BufferCollectionInfo2
12940 {
12941 #[inline]
12942 unsafe fn encode(
12943 self,
12944 encoder: &mut fidl::encoding::Encoder<
12945 '_,
12946 fidl::encoding::DefaultFuchsiaResourceDialect,
12947 >,
12948 offset: usize,
12949 _depth: fidl::encoding::Depth,
12950 ) -> fidl::Result<()> {
12951 encoder.debug_check_bounds::<BufferCollectionInfo2>(offset);
12952 // Delegate to tuple encoding.
12953 fidl::encoding::Encode::<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
12954 (
12955 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffer_count),
12956 <SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow(&self.settings),
12957 <fidl::encoding::Array<VmoBuffer, 64> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffers),
12958 ),
12959 encoder, offset, _depth
12960 )
12961 }
12962 }
12963 unsafe impl<
12964 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12965 T1: fidl::encoding::Encode<SingleBufferSettings, fidl::encoding::DefaultFuchsiaResourceDialect>,
12966 T2: fidl::encoding::Encode<
12967 fidl::encoding::Array<VmoBuffer, 64>,
12968 fidl::encoding::DefaultFuchsiaResourceDialect,
12969 >,
12970 >
12971 fidl::encoding::Encode<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>
12972 for (T0, T1, T2)
12973 {
12974 #[inline]
12975 unsafe fn encode(
12976 self,
12977 encoder: &mut fidl::encoding::Encoder<
12978 '_,
12979 fidl::encoding::DefaultFuchsiaResourceDialect,
12980 >,
12981 offset: usize,
12982 depth: fidl::encoding::Depth,
12983 ) -> fidl::Result<()> {
12984 encoder.debug_check_bounds::<BufferCollectionInfo2>(offset);
12985 // Zero out padding regions. There's no need to apply masks
12986 // because the unmasked parts will be overwritten by fields.
12987 unsafe {
12988 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
12989 (ptr as *mut u64).write_unaligned(0);
12990 }
12991 // Write the fields.
12992 self.0.encode(encoder, offset + 0, depth)?;
12993 self.1.encode(encoder, offset + 8, depth)?;
12994 self.2.encode(encoder, offset + 272, depth)?;
12995 Ok(())
12996 }
12997 }
12998
12999 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13000 for BufferCollectionInfo2
13001 {
13002 #[inline(always)]
13003 fn new_empty() -> Self {
13004 Self {
13005 buffer_count: fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect),
13006 settings: fidl::new_empty!(
13007 SingleBufferSettings,
13008 fidl::encoding::DefaultFuchsiaResourceDialect
13009 ),
13010 buffers: fidl::new_empty!(fidl::encoding::Array<VmoBuffer, 64>, fidl::encoding::DefaultFuchsiaResourceDialect),
13011 }
13012 }
13013
13014 #[inline]
13015 unsafe fn decode(
13016 &mut self,
13017 decoder: &mut fidl::encoding::Decoder<
13018 '_,
13019 fidl::encoding::DefaultFuchsiaResourceDialect,
13020 >,
13021 offset: usize,
13022 _depth: fidl::encoding::Depth,
13023 ) -> fidl::Result<()> {
13024 decoder.debug_check_bounds::<Self>(offset);
13025 // Verify that padding bytes are zero.
13026 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
13027 let padval = unsafe { (ptr as *const u64).read_unaligned() };
13028 let mask = 0xffffffff00000000u64;
13029 let maskedval = padval & mask;
13030 if maskedval != 0 {
13031 return Err(fidl::Error::NonZeroPadding {
13032 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
13033 });
13034 }
13035 fidl::decode!(
13036 u32,
13037 fidl::encoding::DefaultFuchsiaResourceDialect,
13038 &mut self.buffer_count,
13039 decoder,
13040 offset + 0,
13041 _depth
13042 )?;
13043 fidl::decode!(
13044 SingleBufferSettings,
13045 fidl::encoding::DefaultFuchsiaResourceDialect,
13046 &mut self.settings,
13047 decoder,
13048 offset + 8,
13049 _depth
13050 )?;
13051 fidl::decode!(fidl::encoding::Array<VmoBuffer, 64>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.buffers, decoder, offset + 272, _depth)?;
13052 Ok(())
13053 }
13054 }
13055
13056 impl fidl::encoding::ResourceTypeMarker
13057 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13058 {
13059 type Borrowed<'a> = &'a mut Self;
13060 fn take_or_borrow<'a>(
13061 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13062 ) -> Self::Borrowed<'a> {
13063 value
13064 }
13065 }
13066
13067 unsafe impl fidl::encoding::TypeMarker
13068 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13069 {
13070 type Owned = Self;
13071
13072 #[inline(always)]
13073 fn inline_align(_context: fidl::encoding::Context) -> usize {
13074 4
13075 }
13076
13077 #[inline(always)]
13078 fn inline_size(_context: fidl::encoding::Context) -> usize {
13079 4
13080 }
13081 }
13082
13083 unsafe impl
13084 fidl::encoding::Encode<
13085 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13086 fidl::encoding::DefaultFuchsiaResourceDialect,
13087 > for &mut BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13088 {
13089 #[inline]
13090 unsafe fn encode(
13091 self,
13092 encoder: &mut fidl::encoding::Encoder<
13093 '_,
13094 fidl::encoding::DefaultFuchsiaResourceDialect,
13095 >,
13096 offset: usize,
13097 _depth: fidl::encoding::Depth,
13098 ) -> fidl::Result<()> {
13099 encoder
13100 .debug_check_bounds::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
13101 offset,
13102 );
13103 // Delegate to tuple encoding.
13104 fidl::encoding::Encode::<
13105 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13106 fidl::encoding::DefaultFuchsiaResourceDialect,
13107 >::encode(
13108 (<fidl::encoding::Endpoint<
13109 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13110 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13111 &mut self.group_request
13112 ),),
13113 encoder,
13114 offset,
13115 _depth,
13116 )
13117 }
13118 }
13119 unsafe impl<
13120 T0: fidl::encoding::Encode<
13121 fidl::encoding::Endpoint<
13122 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13123 >,
13124 fidl::encoding::DefaultFuchsiaResourceDialect,
13125 >,
13126 >
13127 fidl::encoding::Encode<
13128 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13129 fidl::encoding::DefaultFuchsiaResourceDialect,
13130 > for (T0,)
13131 {
13132 #[inline]
13133 unsafe fn encode(
13134 self,
13135 encoder: &mut fidl::encoding::Encoder<
13136 '_,
13137 fidl::encoding::DefaultFuchsiaResourceDialect,
13138 >,
13139 offset: usize,
13140 depth: fidl::encoding::Depth,
13141 ) -> fidl::Result<()> {
13142 encoder
13143 .debug_check_bounds::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
13144 offset,
13145 );
13146 // Zero out padding regions. There's no need to apply masks
13147 // because the unmasked parts will be overwritten by fields.
13148 // Write the fields.
13149 self.0.encode(encoder, offset + 0, depth)?;
13150 Ok(())
13151 }
13152 }
13153
13154 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13155 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13156 {
13157 #[inline(always)]
13158 fn new_empty() -> Self {
13159 Self {
13160 group_request: fidl::new_empty!(
13161 fidl::encoding::Endpoint<
13162 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13163 >,
13164 fidl::encoding::DefaultFuchsiaResourceDialect
13165 ),
13166 }
13167 }
13168
13169 #[inline]
13170 unsafe fn decode(
13171 &mut self,
13172 decoder: &mut fidl::encoding::Decoder<
13173 '_,
13174 fidl::encoding::DefaultFuchsiaResourceDialect,
13175 >,
13176 offset: usize,
13177 _depth: fidl::encoding::Depth,
13178 ) -> fidl::Result<()> {
13179 decoder.debug_check_bounds::<Self>(offset);
13180 // Verify that padding bytes are zero.
13181 fidl::decode!(
13182 fidl::encoding::Endpoint<
13183 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13184 >,
13185 fidl::encoding::DefaultFuchsiaResourceDialect,
13186 &mut self.group_request,
13187 decoder,
13188 offset + 0,
13189 _depth
13190 )?;
13191 Ok(())
13192 }
13193 }
13194
13195 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateRequest {
13196 type Borrowed<'a> = &'a mut Self;
13197 fn take_or_borrow<'a>(
13198 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13199 ) -> Self::Borrowed<'a> {
13200 value
13201 }
13202 }
13203
13204 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateRequest {
13205 type Owned = Self;
13206
13207 #[inline(always)]
13208 fn inline_align(_context: fidl::encoding::Context) -> usize {
13209 4
13210 }
13211
13212 #[inline(always)]
13213 fn inline_size(_context: fidl::encoding::Context) -> usize {
13214 8
13215 }
13216 }
13217
13218 unsafe impl
13219 fidl::encoding::Encode<
13220 BufferCollectionTokenDuplicateRequest,
13221 fidl::encoding::DefaultFuchsiaResourceDialect,
13222 > for &mut BufferCollectionTokenDuplicateRequest
13223 {
13224 #[inline]
13225 unsafe fn encode(
13226 self,
13227 encoder: &mut fidl::encoding::Encoder<
13228 '_,
13229 fidl::encoding::DefaultFuchsiaResourceDialect,
13230 >,
13231 offset: usize,
13232 _depth: fidl::encoding::Depth,
13233 ) -> fidl::Result<()> {
13234 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateRequest>(offset);
13235 // Delegate to tuple encoding.
13236 fidl::encoding::Encode::<
13237 BufferCollectionTokenDuplicateRequest,
13238 fidl::encoding::DefaultFuchsiaResourceDialect,
13239 >::encode(
13240 (
13241 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.rights_attenuation_mask),
13242 <fidl::encoding::Endpoint<
13243 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
13244 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13245 &mut self.token_request,
13246 ),
13247 ),
13248 encoder,
13249 offset,
13250 _depth,
13251 )
13252 }
13253 }
13254 unsafe impl<
13255 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13256 T1: fidl::encoding::Encode<
13257 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
13258 fidl::encoding::DefaultFuchsiaResourceDialect,
13259 >,
13260 >
13261 fidl::encoding::Encode<
13262 BufferCollectionTokenDuplicateRequest,
13263 fidl::encoding::DefaultFuchsiaResourceDialect,
13264 > for (T0, T1)
13265 {
13266 #[inline]
13267 unsafe fn encode(
13268 self,
13269 encoder: &mut fidl::encoding::Encoder<
13270 '_,
13271 fidl::encoding::DefaultFuchsiaResourceDialect,
13272 >,
13273 offset: usize,
13274 depth: fidl::encoding::Depth,
13275 ) -> fidl::Result<()> {
13276 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateRequest>(offset);
13277 // Zero out padding regions. There's no need to apply masks
13278 // because the unmasked parts will be overwritten by fields.
13279 // Write the fields.
13280 self.0.encode(encoder, offset + 0, depth)?;
13281 self.1.encode(encoder, offset + 4, depth)?;
13282 Ok(())
13283 }
13284 }
13285
13286 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13287 for BufferCollectionTokenDuplicateRequest
13288 {
13289 #[inline(always)]
13290 fn new_empty() -> Self {
13291 Self {
13292 rights_attenuation_mask: fidl::new_empty!(
13293 u32,
13294 fidl::encoding::DefaultFuchsiaResourceDialect
13295 ),
13296 token_request: fidl::new_empty!(
13297 fidl::encoding::Endpoint<
13298 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
13299 >,
13300 fidl::encoding::DefaultFuchsiaResourceDialect
13301 ),
13302 }
13303 }
13304
13305 #[inline]
13306 unsafe fn decode(
13307 &mut self,
13308 decoder: &mut fidl::encoding::Decoder<
13309 '_,
13310 fidl::encoding::DefaultFuchsiaResourceDialect,
13311 >,
13312 offset: usize,
13313 _depth: fidl::encoding::Depth,
13314 ) -> fidl::Result<()> {
13315 decoder.debug_check_bounds::<Self>(offset);
13316 // Verify that padding bytes are zero.
13317 fidl::decode!(
13318 u32,
13319 fidl::encoding::DefaultFuchsiaResourceDialect,
13320 &mut self.rights_attenuation_mask,
13321 decoder,
13322 offset + 0,
13323 _depth
13324 )?;
13325 fidl::decode!(
13326 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
13327 fidl::encoding::DefaultFuchsiaResourceDialect,
13328 &mut self.token_request,
13329 decoder,
13330 offset + 4,
13331 _depth
13332 )?;
13333 Ok(())
13334 }
13335 }
13336
13337 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateSyncResponse {
13338 type Borrowed<'a> = &'a mut Self;
13339 fn take_or_borrow<'a>(
13340 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13341 ) -> Self::Borrowed<'a> {
13342 value
13343 }
13344 }
13345
13346 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateSyncResponse {
13347 type Owned = Self;
13348
13349 #[inline(always)]
13350 fn inline_align(_context: fidl::encoding::Context) -> usize {
13351 8
13352 }
13353
13354 #[inline(always)]
13355 fn inline_size(_context: fidl::encoding::Context) -> usize {
13356 16
13357 }
13358 }
13359
13360 unsafe impl
13361 fidl::encoding::Encode<
13362 BufferCollectionTokenDuplicateSyncResponse,
13363 fidl::encoding::DefaultFuchsiaResourceDialect,
13364 > for &mut BufferCollectionTokenDuplicateSyncResponse
13365 {
13366 #[inline]
13367 unsafe fn encode(
13368 self,
13369 encoder: &mut fidl::encoding::Encoder<
13370 '_,
13371 fidl::encoding::DefaultFuchsiaResourceDialect,
13372 >,
13373 offset: usize,
13374 _depth: fidl::encoding::Depth,
13375 ) -> fidl::Result<()> {
13376 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateSyncResponse>(offset);
13377 // Delegate to tuple encoding.
13378 fidl::encoding::Encode::<
13379 BufferCollectionTokenDuplicateSyncResponse,
13380 fidl::encoding::DefaultFuchsiaResourceDialect,
13381 >::encode(
13382 (<fidl::encoding::Vector<
13383 fidl::encoding::Endpoint<
13384 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13385 >,
13386 64,
13387 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13388 &mut self.tokens
13389 ),),
13390 encoder,
13391 offset,
13392 _depth,
13393 )
13394 }
13395 }
13396 unsafe impl<
13397 T0: fidl::encoding::Encode<
13398 fidl::encoding::Vector<
13399 fidl::encoding::Endpoint<
13400 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13401 >,
13402 64,
13403 >,
13404 fidl::encoding::DefaultFuchsiaResourceDialect,
13405 >,
13406 >
13407 fidl::encoding::Encode<
13408 BufferCollectionTokenDuplicateSyncResponse,
13409 fidl::encoding::DefaultFuchsiaResourceDialect,
13410 > for (T0,)
13411 {
13412 #[inline]
13413 unsafe fn encode(
13414 self,
13415 encoder: &mut fidl::encoding::Encoder<
13416 '_,
13417 fidl::encoding::DefaultFuchsiaResourceDialect,
13418 >,
13419 offset: usize,
13420 depth: fidl::encoding::Depth,
13421 ) -> fidl::Result<()> {
13422 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateSyncResponse>(offset);
13423 // Zero out padding regions. There's no need to apply masks
13424 // because the unmasked parts will be overwritten by fields.
13425 // Write the fields.
13426 self.0.encode(encoder, offset + 0, depth)?;
13427 Ok(())
13428 }
13429 }
13430
13431 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13432 for BufferCollectionTokenDuplicateSyncResponse
13433 {
13434 #[inline(always)]
13435 fn new_empty() -> Self {
13436 Self {
13437 tokens: fidl::new_empty!(
13438 fidl::encoding::Vector<
13439 fidl::encoding::Endpoint<
13440 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13441 >,
13442 64,
13443 >,
13444 fidl::encoding::DefaultFuchsiaResourceDialect
13445 ),
13446 }
13447 }
13448
13449 #[inline]
13450 unsafe fn decode(
13451 &mut self,
13452 decoder: &mut fidl::encoding::Decoder<
13453 '_,
13454 fidl::encoding::DefaultFuchsiaResourceDialect,
13455 >,
13456 offset: usize,
13457 _depth: fidl::encoding::Depth,
13458 ) -> fidl::Result<()> {
13459 decoder.debug_check_bounds::<Self>(offset);
13460 // Verify that padding bytes are zero.
13461 fidl::decode!(
13462 fidl::encoding::Vector<
13463 fidl::encoding::Endpoint<
13464 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13465 >,
13466 64,
13467 >,
13468 fidl::encoding::DefaultFuchsiaResourceDialect,
13469 &mut self.tokens,
13470 decoder,
13471 offset + 0,
13472 _depth
13473 )?;
13474 Ok(())
13475 }
13476 }
13477
13478 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
13479 type Borrowed<'a> = &'a mut Self;
13480 fn take_or_borrow<'a>(
13481 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13482 ) -> Self::Borrowed<'a> {
13483 value
13484 }
13485 }
13486
13487 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
13488 type Owned = Self;
13489
13490 #[inline(always)]
13491 fn inline_align(_context: fidl::encoding::Context) -> usize {
13492 8
13493 }
13494
13495 #[inline(always)]
13496 fn inline_size(_context: fidl::encoding::Context) -> usize {
13497 16
13498 }
13499 }
13500
13501 unsafe impl
13502 fidl::encoding::Encode<
13503 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13504 fidl::encoding::DefaultFuchsiaResourceDialect,
13505 > for &mut BufferCollectionTokenGroupCreateChildrenSyncResponse
13506 {
13507 #[inline]
13508 unsafe fn encode(
13509 self,
13510 encoder: &mut fidl::encoding::Encoder<
13511 '_,
13512 fidl::encoding::DefaultFuchsiaResourceDialect,
13513 >,
13514 offset: usize,
13515 _depth: fidl::encoding::Depth,
13516 ) -> fidl::Result<()> {
13517 encoder
13518 .debug_check_bounds::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(offset);
13519 // Delegate to tuple encoding.
13520 fidl::encoding::Encode::<
13521 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13522 fidl::encoding::DefaultFuchsiaResourceDialect,
13523 >::encode(
13524 (<fidl::encoding::Vector<
13525 fidl::encoding::Endpoint<
13526 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13527 >,
13528 64,
13529 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13530 &mut self.tokens
13531 ),),
13532 encoder,
13533 offset,
13534 _depth,
13535 )
13536 }
13537 }
13538 unsafe impl<
13539 T0: fidl::encoding::Encode<
13540 fidl::encoding::Vector<
13541 fidl::encoding::Endpoint<
13542 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13543 >,
13544 64,
13545 >,
13546 fidl::encoding::DefaultFuchsiaResourceDialect,
13547 >,
13548 >
13549 fidl::encoding::Encode<
13550 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13551 fidl::encoding::DefaultFuchsiaResourceDialect,
13552 > for (T0,)
13553 {
13554 #[inline]
13555 unsafe fn encode(
13556 self,
13557 encoder: &mut fidl::encoding::Encoder<
13558 '_,
13559 fidl::encoding::DefaultFuchsiaResourceDialect,
13560 >,
13561 offset: usize,
13562 depth: fidl::encoding::Depth,
13563 ) -> fidl::Result<()> {
13564 encoder
13565 .debug_check_bounds::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(offset);
13566 // Zero out padding regions. There's no need to apply masks
13567 // because the unmasked parts will be overwritten by fields.
13568 // Write the fields.
13569 self.0.encode(encoder, offset + 0, depth)?;
13570 Ok(())
13571 }
13572 }
13573
13574 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13575 for BufferCollectionTokenGroupCreateChildrenSyncResponse
13576 {
13577 #[inline(always)]
13578 fn new_empty() -> Self {
13579 Self {
13580 tokens: fidl::new_empty!(
13581 fidl::encoding::Vector<
13582 fidl::encoding::Endpoint<
13583 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13584 >,
13585 64,
13586 >,
13587 fidl::encoding::DefaultFuchsiaResourceDialect
13588 ),
13589 }
13590 }
13591
13592 #[inline]
13593 unsafe fn decode(
13594 &mut self,
13595 decoder: &mut fidl::encoding::Decoder<
13596 '_,
13597 fidl::encoding::DefaultFuchsiaResourceDialect,
13598 >,
13599 offset: usize,
13600 _depth: fidl::encoding::Depth,
13601 ) -> fidl::Result<()> {
13602 decoder.debug_check_bounds::<Self>(offset);
13603 // Verify that padding bytes are zero.
13604 fidl::decode!(
13605 fidl::encoding::Vector<
13606 fidl::encoding::Endpoint<
13607 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13608 >,
13609 64,
13610 >,
13611 fidl::encoding::DefaultFuchsiaResourceDialect,
13612 &mut self.tokens,
13613 decoder,
13614 offset + 0,
13615 _depth
13616 )?;
13617 Ok(())
13618 }
13619 }
13620
13621 impl fidl::encoding::ResourceTypeMarker for BufferCollectionWaitForBuffersAllocatedResponse {
13622 type Borrowed<'a> = &'a mut Self;
13623 fn take_or_borrow<'a>(
13624 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13625 ) -> Self::Borrowed<'a> {
13626 value
13627 }
13628 }
13629
13630 unsafe impl fidl::encoding::TypeMarker for BufferCollectionWaitForBuffersAllocatedResponse {
13631 type Owned = Self;
13632
13633 #[inline(always)]
13634 fn inline_align(_context: fidl::encoding::Context) -> usize {
13635 8
13636 }
13637
13638 #[inline(always)]
13639 fn inline_size(_context: fidl::encoding::Context) -> usize {
13640 1304
13641 }
13642 }
13643
13644 unsafe impl
13645 fidl::encoding::Encode<
13646 BufferCollectionWaitForBuffersAllocatedResponse,
13647 fidl::encoding::DefaultFuchsiaResourceDialect,
13648 > for &mut BufferCollectionWaitForBuffersAllocatedResponse
13649 {
13650 #[inline]
13651 unsafe fn encode(
13652 self,
13653 encoder: &mut fidl::encoding::Encoder<
13654 '_,
13655 fidl::encoding::DefaultFuchsiaResourceDialect,
13656 >,
13657 offset: usize,
13658 _depth: fidl::encoding::Depth,
13659 ) -> fidl::Result<()> {
13660 encoder.debug_check_bounds::<BufferCollectionWaitForBuffersAllocatedResponse>(offset);
13661 // Delegate to tuple encoding.
13662 fidl::encoding::Encode::<
13663 BufferCollectionWaitForBuffersAllocatedResponse,
13664 fidl::encoding::DefaultFuchsiaResourceDialect,
13665 >::encode(
13666 (
13667 <i32 as fidl::encoding::ValueTypeMarker>::borrow(&self.status),
13668 <BufferCollectionInfo2 as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13669 &mut self.buffer_collection_info,
13670 ),
13671 ),
13672 encoder,
13673 offset,
13674 _depth,
13675 )
13676 }
13677 }
13678 unsafe impl<
13679 T0: fidl::encoding::Encode<i32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13680 T1: fidl::encoding::Encode<
13681 BufferCollectionInfo2,
13682 fidl::encoding::DefaultFuchsiaResourceDialect,
13683 >,
13684 >
13685 fidl::encoding::Encode<
13686 BufferCollectionWaitForBuffersAllocatedResponse,
13687 fidl::encoding::DefaultFuchsiaResourceDialect,
13688 > for (T0, T1)
13689 {
13690 #[inline]
13691 unsafe fn encode(
13692 self,
13693 encoder: &mut fidl::encoding::Encoder<
13694 '_,
13695 fidl::encoding::DefaultFuchsiaResourceDialect,
13696 >,
13697 offset: usize,
13698 depth: fidl::encoding::Depth,
13699 ) -> fidl::Result<()> {
13700 encoder.debug_check_bounds::<BufferCollectionWaitForBuffersAllocatedResponse>(offset);
13701 // Zero out padding regions. There's no need to apply masks
13702 // because the unmasked parts will be overwritten by fields.
13703 unsafe {
13704 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
13705 (ptr as *mut u64).write_unaligned(0);
13706 }
13707 // Write the fields.
13708 self.0.encode(encoder, offset + 0, depth)?;
13709 self.1.encode(encoder, offset + 8, depth)?;
13710 Ok(())
13711 }
13712 }
13713
13714 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13715 for BufferCollectionWaitForBuffersAllocatedResponse
13716 {
13717 #[inline(always)]
13718 fn new_empty() -> Self {
13719 Self {
13720 status: fidl::new_empty!(i32, fidl::encoding::DefaultFuchsiaResourceDialect),
13721 buffer_collection_info: fidl::new_empty!(
13722 BufferCollectionInfo2,
13723 fidl::encoding::DefaultFuchsiaResourceDialect
13724 ),
13725 }
13726 }
13727
13728 #[inline]
13729 unsafe fn decode(
13730 &mut self,
13731 decoder: &mut fidl::encoding::Decoder<
13732 '_,
13733 fidl::encoding::DefaultFuchsiaResourceDialect,
13734 >,
13735 offset: usize,
13736 _depth: fidl::encoding::Depth,
13737 ) -> fidl::Result<()> {
13738 decoder.debug_check_bounds::<Self>(offset);
13739 // Verify that padding bytes are zero.
13740 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
13741 let padval = unsafe { (ptr as *const u64).read_unaligned() };
13742 let mask = 0xffffffff00000000u64;
13743 let maskedval = padval & mask;
13744 if maskedval != 0 {
13745 return Err(fidl::Error::NonZeroPadding {
13746 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
13747 });
13748 }
13749 fidl::decode!(
13750 i32,
13751 fidl::encoding::DefaultFuchsiaResourceDialect,
13752 &mut self.status,
13753 decoder,
13754 offset + 0,
13755 _depth
13756 )?;
13757 fidl::decode!(
13758 BufferCollectionInfo2,
13759 fidl::encoding::DefaultFuchsiaResourceDialect,
13760 &mut self.buffer_collection_info,
13761 decoder,
13762 offset + 8,
13763 _depth
13764 )?;
13765 Ok(())
13766 }
13767 }
13768
13769 impl fidl::encoding::ResourceTypeMarker for NodeGetNodeRefResponse {
13770 type Borrowed<'a> = &'a mut Self;
13771 fn take_or_borrow<'a>(
13772 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13773 ) -> Self::Borrowed<'a> {
13774 value
13775 }
13776 }
13777
13778 unsafe impl fidl::encoding::TypeMarker for NodeGetNodeRefResponse {
13779 type Owned = Self;
13780
13781 #[inline(always)]
13782 fn inline_align(_context: fidl::encoding::Context) -> usize {
13783 4
13784 }
13785
13786 #[inline(always)]
13787 fn inline_size(_context: fidl::encoding::Context) -> usize {
13788 4
13789 }
13790 }
13791
13792 unsafe impl
13793 fidl::encoding::Encode<
13794 NodeGetNodeRefResponse,
13795 fidl::encoding::DefaultFuchsiaResourceDialect,
13796 > for &mut NodeGetNodeRefResponse
13797 {
13798 #[inline]
13799 unsafe fn encode(
13800 self,
13801 encoder: &mut fidl::encoding::Encoder<
13802 '_,
13803 fidl::encoding::DefaultFuchsiaResourceDialect,
13804 >,
13805 offset: usize,
13806 _depth: fidl::encoding::Depth,
13807 ) -> fidl::Result<()> {
13808 encoder.debug_check_bounds::<NodeGetNodeRefResponse>(offset);
13809 // Delegate to tuple encoding.
13810 fidl::encoding::Encode::<
13811 NodeGetNodeRefResponse,
13812 fidl::encoding::DefaultFuchsiaResourceDialect,
13813 >::encode(
13814 (<fidl::encoding::HandleType<
13815 fidl::Event,
13816 { fidl::ObjectType::EVENT.into_raw() },
13817 2147483648,
13818 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13819 &mut self.node_ref
13820 ),),
13821 encoder,
13822 offset,
13823 _depth,
13824 )
13825 }
13826 }
13827 unsafe impl<
13828 T0: fidl::encoding::Encode<
13829 fidl::encoding::HandleType<
13830 fidl::Event,
13831 { fidl::ObjectType::EVENT.into_raw() },
13832 2147483648,
13833 >,
13834 fidl::encoding::DefaultFuchsiaResourceDialect,
13835 >,
13836 >
13837 fidl::encoding::Encode<
13838 NodeGetNodeRefResponse,
13839 fidl::encoding::DefaultFuchsiaResourceDialect,
13840 > for (T0,)
13841 {
13842 #[inline]
13843 unsafe fn encode(
13844 self,
13845 encoder: &mut fidl::encoding::Encoder<
13846 '_,
13847 fidl::encoding::DefaultFuchsiaResourceDialect,
13848 >,
13849 offset: usize,
13850 depth: fidl::encoding::Depth,
13851 ) -> fidl::Result<()> {
13852 encoder.debug_check_bounds::<NodeGetNodeRefResponse>(offset);
13853 // Zero out padding regions. There's no need to apply masks
13854 // because the unmasked parts will be overwritten by fields.
13855 // Write the fields.
13856 self.0.encode(encoder, offset + 0, depth)?;
13857 Ok(())
13858 }
13859 }
13860
13861 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13862 for NodeGetNodeRefResponse
13863 {
13864 #[inline(always)]
13865 fn new_empty() -> Self {
13866 Self {
13867 node_ref: fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
13868 }
13869 }
13870
13871 #[inline]
13872 unsafe fn decode(
13873 &mut self,
13874 decoder: &mut fidl::encoding::Decoder<
13875 '_,
13876 fidl::encoding::DefaultFuchsiaResourceDialect,
13877 >,
13878 offset: usize,
13879 _depth: fidl::encoding::Depth,
13880 ) -> fidl::Result<()> {
13881 decoder.debug_check_bounds::<Self>(offset);
13882 // Verify that padding bytes are zero.
13883 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.node_ref, decoder, offset + 0, _depth)?;
13884 Ok(())
13885 }
13886 }
13887
13888 impl fidl::encoding::ResourceTypeMarker for NodeIsAlternateForRequest {
13889 type Borrowed<'a> = &'a mut Self;
13890 fn take_or_borrow<'a>(
13891 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13892 ) -> Self::Borrowed<'a> {
13893 value
13894 }
13895 }
13896
13897 unsafe impl fidl::encoding::TypeMarker for NodeIsAlternateForRequest {
13898 type Owned = Self;
13899
13900 #[inline(always)]
13901 fn inline_align(_context: fidl::encoding::Context) -> usize {
13902 4
13903 }
13904
13905 #[inline(always)]
13906 fn inline_size(_context: fidl::encoding::Context) -> usize {
13907 4
13908 }
13909 }
13910
13911 unsafe impl
13912 fidl::encoding::Encode<
13913 NodeIsAlternateForRequest,
13914 fidl::encoding::DefaultFuchsiaResourceDialect,
13915 > for &mut NodeIsAlternateForRequest
13916 {
13917 #[inline]
13918 unsafe fn encode(
13919 self,
13920 encoder: &mut fidl::encoding::Encoder<
13921 '_,
13922 fidl::encoding::DefaultFuchsiaResourceDialect,
13923 >,
13924 offset: usize,
13925 _depth: fidl::encoding::Depth,
13926 ) -> fidl::Result<()> {
13927 encoder.debug_check_bounds::<NodeIsAlternateForRequest>(offset);
13928 // Delegate to tuple encoding.
13929 fidl::encoding::Encode::<
13930 NodeIsAlternateForRequest,
13931 fidl::encoding::DefaultFuchsiaResourceDialect,
13932 >::encode(
13933 (<fidl::encoding::HandleType<
13934 fidl::Event,
13935 { fidl::ObjectType::EVENT.into_raw() },
13936 2147483648,
13937 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13938 &mut self.node_ref
13939 ),),
13940 encoder,
13941 offset,
13942 _depth,
13943 )
13944 }
13945 }
13946 unsafe impl<
13947 T0: fidl::encoding::Encode<
13948 fidl::encoding::HandleType<
13949 fidl::Event,
13950 { fidl::ObjectType::EVENT.into_raw() },
13951 2147483648,
13952 >,
13953 fidl::encoding::DefaultFuchsiaResourceDialect,
13954 >,
13955 >
13956 fidl::encoding::Encode<
13957 NodeIsAlternateForRequest,
13958 fidl::encoding::DefaultFuchsiaResourceDialect,
13959 > for (T0,)
13960 {
13961 #[inline]
13962 unsafe fn encode(
13963 self,
13964 encoder: &mut fidl::encoding::Encoder<
13965 '_,
13966 fidl::encoding::DefaultFuchsiaResourceDialect,
13967 >,
13968 offset: usize,
13969 depth: fidl::encoding::Depth,
13970 ) -> fidl::Result<()> {
13971 encoder.debug_check_bounds::<NodeIsAlternateForRequest>(offset);
13972 // Zero out padding regions. There's no need to apply masks
13973 // because the unmasked parts will be overwritten by fields.
13974 // Write the fields.
13975 self.0.encode(encoder, offset + 0, depth)?;
13976 Ok(())
13977 }
13978 }
13979
13980 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13981 for NodeIsAlternateForRequest
13982 {
13983 #[inline(always)]
13984 fn new_empty() -> Self {
13985 Self {
13986 node_ref: fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
13987 }
13988 }
13989
13990 #[inline]
13991 unsafe fn decode(
13992 &mut self,
13993 decoder: &mut fidl::encoding::Decoder<
13994 '_,
13995 fidl::encoding::DefaultFuchsiaResourceDialect,
13996 >,
13997 offset: usize,
13998 _depth: fidl::encoding::Depth,
13999 ) -> fidl::Result<()> {
14000 decoder.debug_check_bounds::<Self>(offset);
14001 // Verify that padding bytes are zero.
14002 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.node_ref, decoder, offset + 0, _depth)?;
14003 Ok(())
14004 }
14005 }
14006
14007 impl fidl::encoding::ResourceTypeMarker for SingleBufferInfo {
14008 type Borrowed<'a> = &'a mut Self;
14009 fn take_or_borrow<'a>(
14010 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14011 ) -> Self::Borrowed<'a> {
14012 value
14013 }
14014 }
14015
14016 unsafe impl fidl::encoding::TypeMarker for SingleBufferInfo {
14017 type Owned = Self;
14018
14019 #[inline(always)]
14020 fn inline_align(_context: fidl::encoding::Context) -> usize {
14021 8
14022 }
14023
14024 #[inline(always)]
14025 fn inline_size(_context: fidl::encoding::Context) -> usize {
14026 280
14027 }
14028 }
14029
14030 unsafe impl
14031 fidl::encoding::Encode<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
14032 for &mut SingleBufferInfo
14033 {
14034 #[inline]
14035 unsafe fn encode(
14036 self,
14037 encoder: &mut fidl::encoding::Encoder<
14038 '_,
14039 fidl::encoding::DefaultFuchsiaResourceDialect,
14040 >,
14041 offset: usize,
14042 _depth: fidl::encoding::Depth,
14043 ) -> fidl::Result<()> {
14044 encoder.debug_check_bounds::<SingleBufferInfo>(offset);
14045 // Delegate to tuple encoding.
14046 fidl::encoding::Encode::<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
14047 (
14048 <SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow(&self.settings),
14049 <VmoBuffer as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffer),
14050 ),
14051 encoder, offset, _depth
14052 )
14053 }
14054 }
14055 unsafe impl<
14056 T0: fidl::encoding::Encode<SingleBufferSettings, fidl::encoding::DefaultFuchsiaResourceDialect>,
14057 T1: fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>,
14058 > fidl::encoding::Encode<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
14059 for (T0, T1)
14060 {
14061 #[inline]
14062 unsafe fn encode(
14063 self,
14064 encoder: &mut fidl::encoding::Encoder<
14065 '_,
14066 fidl::encoding::DefaultFuchsiaResourceDialect,
14067 >,
14068 offset: usize,
14069 depth: fidl::encoding::Depth,
14070 ) -> fidl::Result<()> {
14071 encoder.debug_check_bounds::<SingleBufferInfo>(offset);
14072 // Zero out padding regions. There's no need to apply masks
14073 // because the unmasked parts will be overwritten by fields.
14074 // Write the fields.
14075 self.0.encode(encoder, offset + 0, depth)?;
14076 self.1.encode(encoder, offset + 264, depth)?;
14077 Ok(())
14078 }
14079 }
14080
14081 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14082 for SingleBufferInfo
14083 {
14084 #[inline(always)]
14085 fn new_empty() -> Self {
14086 Self {
14087 settings: fidl::new_empty!(
14088 SingleBufferSettings,
14089 fidl::encoding::DefaultFuchsiaResourceDialect
14090 ),
14091 buffer: fidl::new_empty!(VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect),
14092 }
14093 }
14094
14095 #[inline]
14096 unsafe fn decode(
14097 &mut self,
14098 decoder: &mut fidl::encoding::Decoder<
14099 '_,
14100 fidl::encoding::DefaultFuchsiaResourceDialect,
14101 >,
14102 offset: usize,
14103 _depth: fidl::encoding::Depth,
14104 ) -> fidl::Result<()> {
14105 decoder.debug_check_bounds::<Self>(offset);
14106 // Verify that padding bytes are zero.
14107 fidl::decode!(
14108 SingleBufferSettings,
14109 fidl::encoding::DefaultFuchsiaResourceDialect,
14110 &mut self.settings,
14111 decoder,
14112 offset + 0,
14113 _depth
14114 )?;
14115 fidl::decode!(
14116 VmoBuffer,
14117 fidl::encoding::DefaultFuchsiaResourceDialect,
14118 &mut self.buffer,
14119 decoder,
14120 offset + 264,
14121 _depth
14122 )?;
14123 Ok(())
14124 }
14125 }
14126
14127 impl fidl::encoding::ResourceTypeMarker for VmoBuffer {
14128 type Borrowed<'a> = &'a mut Self;
14129 fn take_or_borrow<'a>(
14130 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14131 ) -> Self::Borrowed<'a> {
14132 value
14133 }
14134 }
14135
14136 unsafe impl fidl::encoding::TypeMarker for VmoBuffer {
14137 type Owned = Self;
14138
14139 #[inline(always)]
14140 fn inline_align(_context: fidl::encoding::Context) -> usize {
14141 8
14142 }
14143
14144 #[inline(always)]
14145 fn inline_size(_context: fidl::encoding::Context) -> usize {
14146 16
14147 }
14148 }
14149
14150 unsafe impl fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>
14151 for &mut VmoBuffer
14152 {
14153 #[inline]
14154 unsafe fn encode(
14155 self,
14156 encoder: &mut fidl::encoding::Encoder<
14157 '_,
14158 fidl::encoding::DefaultFuchsiaResourceDialect,
14159 >,
14160 offset: usize,
14161 _depth: fidl::encoding::Depth,
14162 ) -> fidl::Result<()> {
14163 encoder.debug_check_bounds::<VmoBuffer>(offset);
14164 // Delegate to tuple encoding.
14165 fidl::encoding::Encode::<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
14166 (
14167 <fidl::encoding::Optional<fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.vmo),
14168 <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.vmo_usable_start),
14169 ),
14170 encoder, offset, _depth
14171 )
14172 }
14173 }
14174 unsafe impl<
14175 T0: fidl::encoding::Encode<
14176 fidl::encoding::Optional<
14177 fidl::encoding::HandleType<
14178 fidl::Vmo,
14179 { fidl::ObjectType::VMO.into_raw() },
14180 2147483648,
14181 >,
14182 >,
14183 fidl::encoding::DefaultFuchsiaResourceDialect,
14184 >,
14185 T1: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
14186 > fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>
14187 for (T0, T1)
14188 {
14189 #[inline]
14190 unsafe fn encode(
14191 self,
14192 encoder: &mut fidl::encoding::Encoder<
14193 '_,
14194 fidl::encoding::DefaultFuchsiaResourceDialect,
14195 >,
14196 offset: usize,
14197 depth: fidl::encoding::Depth,
14198 ) -> fidl::Result<()> {
14199 encoder.debug_check_bounds::<VmoBuffer>(offset);
14200 // Zero out padding regions. There's no need to apply masks
14201 // because the unmasked parts will be overwritten by fields.
14202 unsafe {
14203 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
14204 (ptr as *mut u64).write_unaligned(0);
14205 }
14206 // Write the fields.
14207 self.0.encode(encoder, offset + 0, depth)?;
14208 self.1.encode(encoder, offset + 8, depth)?;
14209 Ok(())
14210 }
14211 }
14212
14213 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect> for VmoBuffer {
14214 #[inline(always)]
14215 fn new_empty() -> Self {
14216 Self {
14217 vmo: fidl::new_empty!(
14218 fidl::encoding::Optional<
14219 fidl::encoding::HandleType<
14220 fidl::Vmo,
14221 { fidl::ObjectType::VMO.into_raw() },
14222 2147483648,
14223 >,
14224 >,
14225 fidl::encoding::DefaultFuchsiaResourceDialect
14226 ),
14227 vmo_usable_start: fidl::new_empty!(
14228 u64,
14229 fidl::encoding::DefaultFuchsiaResourceDialect
14230 ),
14231 }
14232 }
14233
14234 #[inline]
14235 unsafe fn decode(
14236 &mut self,
14237 decoder: &mut fidl::encoding::Decoder<
14238 '_,
14239 fidl::encoding::DefaultFuchsiaResourceDialect,
14240 >,
14241 offset: usize,
14242 _depth: fidl::encoding::Depth,
14243 ) -> fidl::Result<()> {
14244 decoder.debug_check_bounds::<Self>(offset);
14245 // Verify that padding bytes are zero.
14246 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
14247 let padval = unsafe { (ptr as *const u64).read_unaligned() };
14248 let mask = 0xffffffff00000000u64;
14249 let maskedval = padval & mask;
14250 if maskedval != 0 {
14251 return Err(fidl::Error::NonZeroPadding {
14252 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
14253 });
14254 }
14255 fidl::decode!(
14256 fidl::encoding::Optional<
14257 fidl::encoding::HandleType<
14258 fidl::Vmo,
14259 { fidl::ObjectType::VMO.into_raw() },
14260 2147483648,
14261 >,
14262 >,
14263 fidl::encoding::DefaultFuchsiaResourceDialect,
14264 &mut self.vmo,
14265 decoder,
14266 offset + 0,
14267 _depth
14268 )?;
14269 fidl::decode!(
14270 u64,
14271 fidl::encoding::DefaultFuchsiaResourceDialect,
14272 &mut self.vmo_usable_start,
14273 decoder,
14274 offset + 8,
14275 _depth
14276 )?;
14277 Ok(())
14278 }
14279 }
14280
14281 impl BufferCollectionTokenGroupCreateChildRequest {
14282 #[inline(always)]
14283 fn max_ordinal_present(&self) -> u64 {
14284 if let Some(_) = self.rights_attenuation_mask {
14285 return 2;
14286 }
14287 if let Some(_) = self.token_request {
14288 return 1;
14289 }
14290 0
14291 }
14292 }
14293
14294 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildRequest {
14295 type Borrowed<'a> = &'a mut Self;
14296 fn take_or_borrow<'a>(
14297 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14298 ) -> Self::Borrowed<'a> {
14299 value
14300 }
14301 }
14302
14303 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildRequest {
14304 type Owned = Self;
14305
14306 #[inline(always)]
14307 fn inline_align(_context: fidl::encoding::Context) -> usize {
14308 8
14309 }
14310
14311 #[inline(always)]
14312 fn inline_size(_context: fidl::encoding::Context) -> usize {
14313 16
14314 }
14315 }
14316
14317 unsafe impl
14318 fidl::encoding::Encode<
14319 BufferCollectionTokenGroupCreateChildRequest,
14320 fidl::encoding::DefaultFuchsiaResourceDialect,
14321 > for &mut BufferCollectionTokenGroupCreateChildRequest
14322 {
14323 unsafe fn encode(
14324 self,
14325 encoder: &mut fidl::encoding::Encoder<
14326 '_,
14327 fidl::encoding::DefaultFuchsiaResourceDialect,
14328 >,
14329 offset: usize,
14330 mut depth: fidl::encoding::Depth,
14331 ) -> fidl::Result<()> {
14332 encoder.debug_check_bounds::<BufferCollectionTokenGroupCreateChildRequest>(offset);
14333 // Vector header
14334 let max_ordinal: u64 = self.max_ordinal_present();
14335 encoder.write_num(max_ordinal, offset);
14336 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
14337 // Calling encoder.out_of_line_offset(0) is not allowed.
14338 if max_ordinal == 0 {
14339 return Ok(());
14340 }
14341 depth.increment()?;
14342 let envelope_size = 8;
14343 let bytes_len = max_ordinal as usize * envelope_size;
14344 #[allow(unused_variables)]
14345 let offset = encoder.out_of_line_offset(bytes_len);
14346 let mut _prev_end_offset: usize = 0;
14347 if 1 > max_ordinal {
14348 return Ok(());
14349 }
14350
14351 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
14352 // are envelope_size bytes.
14353 let cur_offset: usize = (1 - 1) * envelope_size;
14354
14355 // Zero reserved fields.
14356 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
14357
14358 // Safety:
14359 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
14360 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
14361 // envelope_size bytes, there is always sufficient room.
14362 fidl::encoding::encode_in_envelope_optional::<
14363 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
14364 fidl::encoding::DefaultFuchsiaResourceDialect,
14365 >(
14366 self.token_request.as_mut().map(
14367 <fidl::encoding::Endpoint<
14368 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14369 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
14370 ),
14371 encoder,
14372 offset + cur_offset,
14373 depth,
14374 )?;
14375
14376 _prev_end_offset = cur_offset + envelope_size;
14377 if 2 > max_ordinal {
14378 return Ok(());
14379 }
14380
14381 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
14382 // are envelope_size bytes.
14383 let cur_offset: usize = (2 - 1) * envelope_size;
14384
14385 // Zero reserved fields.
14386 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
14387
14388 // Safety:
14389 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
14390 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
14391 // envelope_size bytes, there is always sufficient room.
14392 fidl::encoding::encode_in_envelope_optional::<
14393 u32,
14394 fidl::encoding::DefaultFuchsiaResourceDialect,
14395 >(
14396 self.rights_attenuation_mask
14397 .as_ref()
14398 .map(<u32 as fidl::encoding::ValueTypeMarker>::borrow),
14399 encoder,
14400 offset + cur_offset,
14401 depth,
14402 )?;
14403
14404 _prev_end_offset = cur_offset + envelope_size;
14405
14406 Ok(())
14407 }
14408 }
14409
14410 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14411 for BufferCollectionTokenGroupCreateChildRequest
14412 {
14413 #[inline(always)]
14414 fn new_empty() -> Self {
14415 Self::default()
14416 }
14417
14418 unsafe fn decode(
14419 &mut self,
14420 decoder: &mut fidl::encoding::Decoder<
14421 '_,
14422 fidl::encoding::DefaultFuchsiaResourceDialect,
14423 >,
14424 offset: usize,
14425 mut depth: fidl::encoding::Depth,
14426 ) -> fidl::Result<()> {
14427 decoder.debug_check_bounds::<Self>(offset);
14428 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
14429 None => return Err(fidl::Error::NotNullable),
14430 Some(len) => len,
14431 };
14432 // Calling decoder.out_of_line_offset(0) is not allowed.
14433 if len == 0 {
14434 return Ok(());
14435 };
14436 depth.increment()?;
14437 let envelope_size = 8;
14438 let bytes_len = len * envelope_size;
14439 let offset = decoder.out_of_line_offset(bytes_len)?;
14440 // Decode the envelope for each type.
14441 let mut _next_ordinal_to_read = 0;
14442 let mut next_offset = offset;
14443 let end_offset = offset + bytes_len;
14444 _next_ordinal_to_read += 1;
14445 if next_offset >= end_offset {
14446 return Ok(());
14447 }
14448
14449 // Decode unknown envelopes for gaps in ordinals.
14450 while _next_ordinal_to_read < 1 {
14451 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14452 _next_ordinal_to_read += 1;
14453 next_offset += envelope_size;
14454 }
14455
14456 let next_out_of_line = decoder.next_out_of_line();
14457 let handles_before = decoder.remaining_handles();
14458 if let Some((inlined, num_bytes, num_handles)) =
14459 fidl::encoding::decode_envelope_header(decoder, next_offset)?
14460 {
14461 let member_inline_size = <fidl::encoding::Endpoint<
14462 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14463 > as fidl::encoding::TypeMarker>::inline_size(
14464 decoder.context
14465 );
14466 if inlined != (member_inline_size <= 4) {
14467 return Err(fidl::Error::InvalidInlineBitInEnvelope);
14468 }
14469 let inner_offset;
14470 let mut inner_depth = depth.clone();
14471 if inlined {
14472 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
14473 inner_offset = next_offset;
14474 } else {
14475 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
14476 inner_depth.increment()?;
14477 }
14478 let val_ref = self.token_request.get_or_insert_with(|| {
14479 fidl::new_empty!(
14480 fidl::encoding::Endpoint<
14481 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14482 >,
14483 fidl::encoding::DefaultFuchsiaResourceDialect
14484 )
14485 });
14486 fidl::decode!(
14487 fidl::encoding::Endpoint<
14488 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14489 >,
14490 fidl::encoding::DefaultFuchsiaResourceDialect,
14491 val_ref,
14492 decoder,
14493 inner_offset,
14494 inner_depth
14495 )?;
14496 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
14497 {
14498 return Err(fidl::Error::InvalidNumBytesInEnvelope);
14499 }
14500 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
14501 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
14502 }
14503 }
14504
14505 next_offset += envelope_size;
14506 _next_ordinal_to_read += 1;
14507 if next_offset >= end_offset {
14508 return Ok(());
14509 }
14510
14511 // Decode unknown envelopes for gaps in ordinals.
14512 while _next_ordinal_to_read < 2 {
14513 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14514 _next_ordinal_to_read += 1;
14515 next_offset += envelope_size;
14516 }
14517
14518 let next_out_of_line = decoder.next_out_of_line();
14519 let handles_before = decoder.remaining_handles();
14520 if let Some((inlined, num_bytes, num_handles)) =
14521 fidl::encoding::decode_envelope_header(decoder, next_offset)?
14522 {
14523 let member_inline_size =
14524 <u32 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
14525 if inlined != (member_inline_size <= 4) {
14526 return Err(fidl::Error::InvalidInlineBitInEnvelope);
14527 }
14528 let inner_offset;
14529 let mut inner_depth = depth.clone();
14530 if inlined {
14531 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
14532 inner_offset = next_offset;
14533 } else {
14534 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
14535 inner_depth.increment()?;
14536 }
14537 let val_ref = self.rights_attenuation_mask.get_or_insert_with(|| {
14538 fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect)
14539 });
14540 fidl::decode!(
14541 u32,
14542 fidl::encoding::DefaultFuchsiaResourceDialect,
14543 val_ref,
14544 decoder,
14545 inner_offset,
14546 inner_depth
14547 )?;
14548 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
14549 {
14550 return Err(fidl::Error::InvalidNumBytesInEnvelope);
14551 }
14552 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
14553 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
14554 }
14555 }
14556
14557 next_offset += envelope_size;
14558
14559 // Decode the remaining unknown envelopes.
14560 while next_offset < end_offset {
14561 _next_ordinal_to_read += 1;
14562 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14563 next_offset += envelope_size;
14564 }
14565
14566 Ok(())
14567 }
14568 }
14569}