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 Self { client: fidl::client::sync::Client::new(channel) }
304 }
305
306 pub fn into_channel(self) -> fidl::Channel {
307 self.client.into_channel()
308 }
309
310 /// Waits until an event arrives and returns it. It is safe for other
311 /// threads to make concurrent requests while waiting for an event.
312 pub fn wait_for_event(
313 &self,
314 deadline: zx::MonotonicInstant,
315 ) -> Result<AllocatorEvent, fidl::Error> {
316 AllocatorEvent::decode(self.client.wait_for_event::<AllocatorMarker>(deadline)?)
317 }
318
319 /// Allocates a BufferCollection on behalf of a single client (aka initiator)
320 /// who is also the only participant (from the point of view of sysmem).
321 ///
322 /// This call exists mainly for temp/testing purposes. This call skips the
323 /// BufferCollectionToken stage, so there's no way to allow another
324 /// participant to specify its constraints.
325 ///
326 /// Real clients are encouraged to use AllocateSharedCollection() instead,
327 /// and to let relevant participants directly convey their own constraints to
328 /// sysmem.
329 ///
330 /// `collection_request` is the server end of the BufferCollection FIDL
331 /// channel. The client can call SetConstraints() and then
332 /// WaitForBuffersAllocated() on the client end of this channel to specify
333 /// constraints and then determine success/failure and get the
334 /// BufferCollectionInfo_2 for the BufferCollection. The client should also
335 /// keep the client end of this channel open while using the
336 /// BufferCollection, and should notice when this channel closes and stop
337 /// using the BufferCollection ASAP.
338 pub fn r#allocate_non_shared_collection(
339 &self,
340 mut collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
341 ) -> Result<(), fidl::Error> {
342 self.client.send::<AllocatorAllocateNonSharedCollectionRequest>(
343 (collection_request,),
344 0x20f79299bbb4d2c6,
345 fidl::encoding::DynamicFlags::empty(),
346 )
347 }
348
349 /// Creates a logical BufferCollectionToken which can be shared among
350 /// participants (using BufferCollectionToken.Duplicate()), and then
351 /// converted into a BufferCollection using BindSharedCollection().
352 ///
353 /// Success/failure to populate the BufferCollection with buffers is
354 /// determined via the BufferCollection interface.
355 pub fn r#allocate_shared_collection(
356 &self,
357 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
358 ) -> Result<(), fidl::Error> {
359 self.client.send::<AllocatorAllocateSharedCollectionRequest>(
360 (token_request,),
361 0x7a757a57bfda0f71,
362 fidl::encoding::DynamicFlags::empty(),
363 )
364 }
365
366 /// Convert a BufferCollectionToken into a connection to the logical
367 /// BufferCollection. The BufferCollection hasn't yet been populated with
368 /// buffers - the participant must first also send SetConstraints() via the
369 /// client end of buffer_collection.
370 ///
371 /// All BufferCollectionToken(s) duplicated from a logical
372 /// BufferCollectionToken created via AllocateSharedCollection() must be
373 /// turned in via BindSharedCollection() before the logical BufferCollection
374 /// will be populated with buffers.
375 ///
376 /// `token` the client endpoint of a channel whose server end was sent to
377 /// sysmem using AllocateSharedCollection or whose server end was sent to
378 /// sysmem using BufferCollectionToken.Duplicate(). The token is being
379 /// "exchanged" for a channel to the logical BufferCollection.
380 ///
381 /// `buffer_collection_request` the server end of a BufferCollection
382 /// channel. The sender retains the client end as usual. The
383 /// BufferCollection channel is a single participant's connection to the
384 /// logical BufferCollection. There typically will be other participants
385 /// with their own BufferCollection channel to the logical BufferCollection.
386 pub fn r#bind_shared_collection(
387 &self,
388 mut token: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
389 mut buffer_collection_request: fidl::endpoints::ServerEnd<BufferCollectionMarker>,
390 ) -> Result<(), fidl::Error> {
391 self.client.send::<AllocatorBindSharedCollectionRequest>(
392 (token, buffer_collection_request),
393 0x146eca7ec46ff4ee,
394 fidl::encoding::DynamicFlags::empty(),
395 )
396 }
397
398 /// Validate that a BufferCollectionToken is known to the sysmem server.
399 ///
400 /// This can be used in cases where BindSharedCollection() won't be called
401 /// until after BufferCollectionToken.Duplicate() +
402 /// BufferCollectionToken.Sync(), when the client code wants to know earlier
403 /// whether an incoming token is valid (so far).
404 ///
405 /// Calling BufferCollectionToken.Sync() on a token that isn't known to
406 /// sysmem risks the Sync() hanging forever.
407 ///
408 /// Given that an incoming token can become invalid at any time if any
409 /// participant drops their BufferCollectionToken(s) or BufferCollection(s),
410 /// authors of client code are encouraged to consider not calling
411 /// ValidateBufferCollectionToken() and instead dealing with async failure
412 /// of the BufferCollection.Sync() after all the
413 /// BufferCollectionToken.Duplicate() and BindSharedCollection() (before
414 /// sending any duplicate tokens to other processes).
415 ///
416 /// Regardless of the result of this call, this call has no effect on the
417 /// token with the referenced koid.
418 ///
419 /// A true result from this call doesn't guarantee that the token remains
420 /// valid for any duration afterwards.
421 ///
422 /// Client code will zx_object_get_info() on the client's token handle,
423 /// passing ZX_INFO_HANDLE_BASIC and getting back the related_koid
424 /// which then gets passed to ValidateBufferCollectionToken().
425 ///
426 /// If ValidateBufferCollectionToken() returns true, the token was known at
427 /// the time the sysmem server processed the call, but may no longer be
428 /// valid/known by the time the client code receives the response.
429 ///
430 /// If ValidateBufferCollectionToken() returns false, the token wasn't known
431 /// at the time the sysmem server processed the call, but the token may
432 /// become known by the time the client code receives the response. However
433 /// client code is not required to mitigate the possibility that the token
434 /// may become known late, since the source of the token should have synced
435 /// the token to sysmem before sending the token to the client code.
436 ///
437 /// If calling ValidateBufferCollectionToken() fails in some way, there will
438 /// be a zx_status_t from the FIDL layer.
439 ///
440 /// `token_server_koid` the koid of the server end of a channel that might
441 /// be a BufferCollectionToken channel. This can be obtained from
442 /// zx_object_get_info() ZX_INFO_HANDLE_BASIC related_koid.
443 pub fn r#validate_buffer_collection_token(
444 &self,
445 mut token_server_koid: u64,
446 ___deadline: zx::MonotonicInstant,
447 ) -> Result<bool, fidl::Error> {
448 let _response = self.client.send_query::<
449 AllocatorValidateBufferCollectionTokenRequest,
450 AllocatorValidateBufferCollectionTokenResponse,
451 AllocatorMarker,
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 AllocatorControlHandle {
1271 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
1272 self.inner.shutdown_with_epitaph(status.into())
1273 }
1274}
1275
1276impl fidl::endpoints::ControlHandle for AllocatorControlHandle {
1277 fn shutdown(&self) {
1278 self.inner.shutdown()
1279 }
1280
1281 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
1282 self.inner.shutdown_with_epitaph(status)
1283 }
1284
1285 fn is_closed(&self) -> bool {
1286 self.inner.channel().is_closed()
1287 }
1288 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1289 self.inner.channel().on_closed()
1290 }
1291
1292 #[cfg(target_os = "fuchsia")]
1293 fn signal_peer(
1294 &self,
1295 clear_mask: zx::Signals,
1296 set_mask: zx::Signals,
1297 ) -> Result<(), zx_status::Status> {
1298 use fidl::Peered;
1299 self.inner.channel().signal_peer(clear_mask, set_mask)
1300 }
1301}
1302
1303impl AllocatorControlHandle {}
1304
1305#[must_use = "FIDL methods require a response to be sent"]
1306#[derive(Debug)]
1307pub struct AllocatorValidateBufferCollectionTokenResponder {
1308 control_handle: std::mem::ManuallyDrop<AllocatorControlHandle>,
1309 tx_id: u32,
1310}
1311
1312/// Set the the channel to be shutdown (see [`AllocatorControlHandle::shutdown`])
1313/// if the responder is dropped without sending a response, so that the client
1314/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1315impl std::ops::Drop for AllocatorValidateBufferCollectionTokenResponder {
1316 fn drop(&mut self) {
1317 self.control_handle.shutdown();
1318 // Safety: drops once, never accessed again
1319 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1320 }
1321}
1322
1323impl fidl::endpoints::Responder for AllocatorValidateBufferCollectionTokenResponder {
1324 type ControlHandle = AllocatorControlHandle;
1325
1326 fn control_handle(&self) -> &AllocatorControlHandle {
1327 &self.control_handle
1328 }
1329
1330 fn drop_without_shutdown(mut self) {
1331 // Safety: drops once, never accessed again due to mem::forget
1332 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1333 // Prevent Drop from running (which would shut down the channel)
1334 std::mem::forget(self);
1335 }
1336}
1337
1338impl AllocatorValidateBufferCollectionTokenResponder {
1339 /// Sends a response to the FIDL transaction.
1340 ///
1341 /// Sets the channel to shutdown if an error occurs.
1342 pub fn send(self, mut is_known: bool) -> Result<(), fidl::Error> {
1343 let _result = self.send_raw(is_known);
1344 if _result.is_err() {
1345 self.control_handle.shutdown();
1346 }
1347 self.drop_without_shutdown();
1348 _result
1349 }
1350
1351 /// Similar to "send" but does not shutdown the channel if an error occurs.
1352 pub fn send_no_shutdown_on_err(self, mut is_known: bool) -> Result<(), fidl::Error> {
1353 let _result = self.send_raw(is_known);
1354 self.drop_without_shutdown();
1355 _result
1356 }
1357
1358 fn send_raw(&self, mut is_known: bool) -> Result<(), fidl::Error> {
1359 self.control_handle.inner.send::<AllocatorValidateBufferCollectionTokenResponse>(
1360 (is_known,),
1361 self.tx_id,
1362 0x575b279b0236faea,
1363 fidl::encoding::DynamicFlags::empty(),
1364 )
1365 }
1366}
1367
1368#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1369pub struct BufferCollectionMarker;
1370
1371impl fidl::endpoints::ProtocolMarker for BufferCollectionMarker {
1372 type Proxy = BufferCollectionProxy;
1373 type RequestStream = BufferCollectionRequestStream;
1374 #[cfg(target_os = "fuchsia")]
1375 type SynchronousProxy = BufferCollectionSynchronousProxy;
1376
1377 const DEBUG_NAME: &'static str = "(anonymous) BufferCollection";
1378}
1379
1380pub trait BufferCollectionProxyInterface: Send + Sync {
1381 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
1382 fn r#sync(&self) -> Self::SyncResponseFut;
1383 fn r#close(&self) -> Result<(), fidl::Error>;
1384 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
1385 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
1386 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
1387 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
1388 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
1389 + Send;
1390 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
1391 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
1392 + Send;
1393 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
1394 fn r#set_constraints(
1395 &self,
1396 has_constraints: bool,
1397 constraints: &BufferCollectionConstraints,
1398 ) -> Result<(), fidl::Error>;
1399 type WaitForBuffersAllocatedResponseFut: std::future::Future<Output = Result<(i32, BufferCollectionInfo2), fidl::Error>>
1400 + Send;
1401 fn r#wait_for_buffers_allocated(&self) -> Self::WaitForBuffersAllocatedResponseFut;
1402 type CheckBuffersAllocatedResponseFut: std::future::Future<Output = Result<i32, fidl::Error>>
1403 + Send;
1404 fn r#check_buffers_allocated(&self) -> Self::CheckBuffersAllocatedResponseFut;
1405 fn r#attach_token(
1406 &self,
1407 rights_attenuation_mask: u32,
1408 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
1409 ) -> Result<(), fidl::Error>;
1410 fn r#attach_lifetime_tracking(
1411 &self,
1412 server_end: fidl::EventPair,
1413 buffers_remaining: u32,
1414 ) -> Result<(), fidl::Error>;
1415}
1416#[derive(Debug)]
1417#[cfg(target_os = "fuchsia")]
1418pub struct BufferCollectionSynchronousProxy {
1419 client: fidl::client::sync::Client,
1420}
1421
1422#[cfg(target_os = "fuchsia")]
1423impl fidl::endpoints::SynchronousProxy for BufferCollectionSynchronousProxy {
1424 type Proxy = BufferCollectionProxy;
1425 type Protocol = BufferCollectionMarker;
1426
1427 fn from_channel(inner: fidl::Channel) -> Self {
1428 Self::new(inner)
1429 }
1430
1431 fn into_channel(self) -> fidl::Channel {
1432 self.client.into_channel()
1433 }
1434
1435 fn as_channel(&self) -> &fidl::Channel {
1436 self.client.as_channel()
1437 }
1438}
1439
1440#[cfg(target_os = "fuchsia")]
1441impl BufferCollectionSynchronousProxy {
1442 pub fn new(channel: fidl::Channel) -> Self {
1443 Self { client: fidl::client::sync::Client::new(channel) }
1444 }
1445
1446 pub fn into_channel(self) -> fidl::Channel {
1447 self.client.into_channel()
1448 }
1449
1450 /// Waits until an event arrives and returns it. It is safe for other
1451 /// threads to make concurrent requests while waiting for an event.
1452 pub fn wait_for_event(
1453 &self,
1454 deadline: zx::MonotonicInstant,
1455 ) -> Result<BufferCollectionEvent, fidl::Error> {
1456 BufferCollectionEvent::decode(
1457 self.client.wait_for_event::<BufferCollectionMarker>(deadline)?,
1458 )
1459 }
1460
1461 /// Ensure that previous messages, including Duplicate() messages on a
1462 /// token, collection, or group, have been received server side.
1463 ///
1464 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
1465 /// valid sysmem token risks the Sync() hanging forever. See
1466 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
1467 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
1468 /// Another way is to pass the token to BindSharedCollection(), which also
1469 /// validates the token as part of exchanging it for a BufferCollection
1470 /// channel, and BufferCollection Sync() can then be used.
1471 ///
1472 /// After a Sync(), it's then safe to send the client end of token_request
1473 /// to another participant knowing the server will recognize the token when
1474 /// it's sent into BindSharedCollection() by the other participant.
1475 ///
1476 /// Other options include waiting for each token.Duplicate() to complete
1477 /// individually (using separate call to token.Sync() after each), or
1478 /// calling Sync() on BufferCollection after the token has been turned in
1479 /// via BindSharedCollection().
1480 ///
1481 /// Another way to mitigate is to avoid calling Sync() on the token, and
1482 /// instead later deal with potential failure of BufferCollection.Sync() if
1483 /// the original token was invalid. This option can be preferable from a
1484 /// performance point of view, but requires client code to delay sending
1485 /// tokens duplicated from this token until after client code has converted
1486 /// the duplicating token to a BufferCollection and received successful
1487 /// response from BufferCollection.Sync().
1488 ///
1489 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
1490 /// When BufferCollection.Sync() isn't feasible, the caller must already
1491 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
1492 /// hang forever. See ValidateBufferCollectionToken() to check token
1493 /// validity first if the token isn't already known to be (is/was) valid.
1494 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
1495 let _response = self.client.send_query::<
1496 fidl::encoding::EmptyPayload,
1497 fidl::encoding::EmptyPayload,
1498 BufferCollectionMarker,
1499 >(
1500 (),
1501 0x4577e238ae26291,
1502 fidl::encoding::DynamicFlags::empty(),
1503 ___deadline,
1504 )?;
1505 Ok(_response)
1506 }
1507
1508 /// On a BufferCollectionToken channel:
1509 ///
1510 /// Normally a participant will convert a BufferCollectionToken into a
1511 /// BufferCollection view, but a participant is also free to Close() the
1512 /// token (and then close the channel immediately or shortly later in
1513 /// response to server closing its end), which avoids causing logical buffer
1514 /// collection failure. Â Normally an unexpected token channel close will
1515 /// cause logical buffer collection failure (the only exceptions being
1516 /// certain cases involving AttachToken() or SetDispensable()).
1517 ///
1518 /// On a BufferCollection channel:
1519 ///
1520 /// By default the server handles unexpected failure of a BufferCollection
1521 /// by failing the whole logical buffer collection. Partly this is to
1522 /// expedite closing VMO handles to reclaim memory when any participant
1523 /// fails. If a participant would like to cleanly close a BufferCollection
1524 /// view without causing logical buffer collection failure, the participant
1525 /// can send Close() before closing the client end of the BufferCollection
1526 /// channel. If this is the last BufferCollection view, the logical buffer
1527 /// collection will still go away. The Close() can occur before or after
1528 /// SetConstraints(). If before SetConstraints(), the buffer collection
1529 /// won't require constraints from this node in order to allocate. If
1530 /// after SetConstraints(), the constraints are retained and aggregated
1531 /// along with any subsequent logical allocation(s), despite the lack of
1532 /// channel connection.
1533 ///
1534 /// On a BufferCollectionTokenGroup channel:
1535 ///
1536 /// By default, unexpected failure of a BufferCollectionTokenGroup will
1537 /// trigger failure of the logical BufferCollectionTokenGroup and will
1538 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
1539 /// channel without failing the logical group or propagating failure, send
1540 /// Close() before closing the channel client endpoint.
1541 ///
1542 /// If Close() occurs before AllChildrenPresent(), the logical buffer
1543 /// collection will still fail despite the Close() (because sysmem can't be
1544 /// sure whether all relevant children were created, so it's ambiguous
1545 /// whether all relevant constraints will be provided to sysmem). If
1546 /// Close() occurs after AllChildrenPresent(), the children and all their
1547 /// constraints remain intact (just as they would if the
1548 /// BufferCollectionTokenGroup channel had remained open), and the close
1549 /// doesn't trigger or propagate failure.
1550 pub fn r#close(&self) -> Result<(), fidl::Error> {
1551 self.client.send::<fidl::encoding::EmptyPayload>(
1552 (),
1553 0x5b1d7a4f5681fca7,
1554 fidl::encoding::DynamicFlags::empty(),
1555 )
1556 }
1557
1558 /// Set a name for VMOs in this buffer collection. The name may be truncated
1559 /// shorter. The name only affects VMOs allocated after it's set - this call
1560 /// does not rename existing VMOs. If multiple clients set different names
1561 /// then the larger priority value will win.
1562 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
1563 self.client.send::<NodeSetNameRequest>(
1564 (priority, name),
1565 0x77a41bb6217e2443,
1566 fidl::encoding::DynamicFlags::empty(),
1567 )
1568 }
1569
1570 /// Set information about the current client that can be used by sysmem to
1571 /// help debug leaking memory and hangs waiting for constraints. |name| can
1572 /// be an arbitrary string, but the current process name (see
1573 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
1574 /// arbitrary id, but the current process ID (see
1575 /// fsl::GetCurrentProcessKoid()) is a good default.
1576 ///
1577 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
1578 /// indicate which client is closing their channel first, leading to
1579 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
1580 /// over, but if happening earlier than expected, the
1581 /// client-channel-specific name can help diagnose where the failure is
1582 /// first coming from, from sysmem's point of view).
1583 ///
1584 /// By default (unless overriden by this message or using
1585 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
1586 /// parent Node at the time the child Node is created. While this can be
1587 /// better than nothing, it's often better for each participant to use
1588 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
1589 /// info directly relevant to the current client. Also, SetVerboseLogging()
1590 /// can be used to help disambiguate if a Node is suspected of having info
1591 /// that was copied from its parent.
1592 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
1593 self.client.send::<NodeSetDebugClientInfoRequest>(
1594 (name, id),
1595 0x7275759070eb5ee2,
1596 fidl::encoding::DynamicFlags::empty(),
1597 )
1598 }
1599
1600 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
1601 /// after creating a collection. Clients can call this method to change
1602 /// when the log is printed. If multiple client set the deadline, it's
1603 /// unspecified which deadline will take effect.
1604 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
1605 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
1606 (deadline,),
1607 0x46d38f4772638867,
1608 fidl::encoding::DynamicFlags::empty(),
1609 )
1610 }
1611
1612 /// Verbose logging includes constraints set via SetConstraints() from each
1613 /// client along with info set via SetDebugClientInfo() and the structure of
1614 /// the tree of Node(s).
1615 ///
1616 /// Normally sysmem prints only a single line complaint when aggregation
1617 /// fails, with just the specific detailed reason that aggregation failed,
1618 /// with minimal context. While this is often enough to diagnose a problem
1619 /// if only a small change was made and the system had been working before
1620 /// the small change, it's often not particularly helpful for getting a new
1621 /// buffer collection to work for the first time. Especially with more
1622 /// complex trees of nodes, involving things like AttachToken(),
1623 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
1624 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
1625 /// looks like and why it's failing a logical allocation, or why a tree or
1626 /// sub-tree is failing sooner than expected.
1627 ///
1628 /// The intent of the extra logging is to be acceptable from a performance
1629 /// point of view, if only enabled on a low number of buffer collections.
1630 /// If we're not tracking down a bug, we shouldn't send this message.
1631 ///
1632 /// If too many participants leave verbose logging enabled, we may end up
1633 /// needing to require that system-wide sysmem verbose logging be permitted
1634 /// via some other setting, to avoid sysmem spamming the log too much due to
1635 /// this message.
1636 ///
1637 /// This may be a NOP for some nodes due to intentional policy associated
1638 /// with the node, if we don't trust a node enough to let it turn on verbose
1639 /// logging.
1640 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
1641 self.client.send::<fidl::encoding::EmptyPayload>(
1642 (),
1643 0x6bfbe2cf1701d288,
1644 fidl::encoding::DynamicFlags::empty(),
1645 )
1646 }
1647
1648 /// This gets an event handle that can be used as a parameter to
1649 /// IsAlternateFor() called on any Node. The client will not be granted the
1650 /// right to signal this event, as this handle should only be used as proof
1651 /// that the client obtained this handle from this Node.
1652 ///
1653 /// Because this is a get not a set, no Sync() is needed between the
1654 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
1655 /// potentially being on different channels.
1656 ///
1657 /// See also IsAlternateFor().
1658 pub fn r#get_node_ref(
1659 &self,
1660 ___deadline: zx::MonotonicInstant,
1661 ) -> Result<fidl::Event, fidl::Error> {
1662 let _response = self.client.send_query::<
1663 fidl::encoding::EmptyPayload,
1664 NodeGetNodeRefResponse,
1665 BufferCollectionMarker,
1666 >(
1667 (),
1668 0x467b7c75c35c3b84,
1669 fidl::encoding::DynamicFlags::empty(),
1670 ___deadline,
1671 )?;
1672 Ok(_response.node_ref)
1673 }
1674
1675 /// This checks whether the calling node is in a subtree rooted at a
1676 /// different child token of a common parent BufferCollectionTokenGroup, in
1677 /// relation to the passed-in node_ref.
1678 ///
1679 /// This call is for assisting with admission control de-duplication, and
1680 /// with debugging.
1681 ///
1682 /// The node_ref must be obtained using GetNodeRef() of a
1683 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
1684 ///
1685 /// The node_ref can be a duplicated handle; it's not necessary to call
1686 /// GetNodeRef() for every call to IsAlternateFor().
1687 ///
1688 /// If a calling token may not actually be a valid token at all due to
1689 /// a potentially hostile/untrusted provider of the token, call
1690 /// ValidateBufferCollectionToken() first instead of potentially getting
1691 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
1692 /// token not being a real token (not really talking to sysmem). Another
1693 /// option is to call BindSharedCollection with this token first which also
1694 /// validates the token along with converting it to a BufferCollection, then
1695 /// call BufferCollection IsAlternateFor().
1696 ///
1697 /// error values:
1698 ///
1699 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
1700 /// buffer collection as the calling Node. Before logical allocation and
1701 /// within the same logical allocation sub-tree, this essentially means that
1702 /// the node_ref was never part of this logical buffer collection, since
1703 /// before logical allocation all node_refs that come into existence remain
1704 /// in existence at least until logical allocation (including Node(s) that
1705 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
1706 /// to be returned, this Node's channel needs to still be connected server
1707 /// side, which won't be the case if the whole logical allocation has
1708 /// failed. After logical allocation or in a different logical allocation
1709 /// sub-tree there are additional potential reasons for this error. For
1710 /// example a different logical allocation (separated from this Node(s)
1711 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
1712 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
1713 /// exist and may select a different child sub-tree than the sub-tree the
1714 /// node_ref is in causing deletion of the node_ref Node. The only time
1715 /// sysmem keeps a Node around after that Node has no corresponding channel
1716 /// is when Close() is used and the Node's sub-tree has not yet failed.
1717 /// Another reason for this error is if the node_ref is an eventpair handle
1718 /// with sufficient rights, but isn't actually a real node_ref obtained from
1719 /// GetNodeRef().
1720 ///
1721 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
1722 /// eventpair handle, or doesn't have the needed rights expected on a real
1723 /// node_ref.
1724 ///
1725 /// No other failing status codes are returned by this call. However,
1726 /// sysmem may add additional codes in future, so the client should have
1727 /// sensible default handling for any failing status code.
1728 ///
1729 /// On success, is_alternate has the following meaning:
1730 /// * true - The first parent node in common between the calling node and
1731 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
1732 /// the calling Node and the node_ref Node will _not_ have both their
1733 /// constraints apply - rather sysmem will choose one or the other of
1734 /// the constraints - never both. This is because only one child of
1735 /// a BufferCollectionTokenGroup is selected during logical allocation,
1736 /// with only that one child's sub-tree contributing to constraints
1737 /// aggregation.
1738 /// * false - The first parent node in common between the calling Node and
1739 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
1740 /// this means the first parent node in common is a
1741 /// BufferCollectionToken or BufferCollection (regardless of not
1742 /// Close()ed or Close()ed). This means that the calling Node and the
1743 /// node_ref Node _may_ have both their constraints apply during
1744 /// constraints aggregation of the logical allocation, if both Node(s)
1745 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
1746 /// In this case, there is no BufferCollectionTokenGroup that will
1747 /// directly prevent the two Node(s) from both being selected and their
1748 /// constraints both aggregated, but even when false, one or both
1749 /// Node(s) may still be eliminated from consideration if one or both
1750 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
1751 /// which selects a child sub-tree other than the sub-tree containing
1752 /// the calling Node or node_ref Node.
1753 pub fn r#is_alternate_for(
1754 &self,
1755 mut node_ref: fidl::Event,
1756 ___deadline: zx::MonotonicInstant,
1757 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
1758 let _response = self.client.send_query::<
1759 NodeIsAlternateForRequest,
1760 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
1761 BufferCollectionMarker,
1762 >(
1763 (node_ref,),
1764 0x33a2a7aff2776c07,
1765 fidl::encoding::DynamicFlags::empty(),
1766 ___deadline,
1767 )?;
1768 Ok(_response.map(|x| x.is_alternate))
1769 }
1770
1771 /// Provide BufferCollectionConstraints to the logical BufferCollection.
1772 ///
1773 /// A participant may only call SetConstraints() once.
1774 ///
1775 /// Sometimes the initiator is a participant only in the sense of wanting to
1776 /// keep an eye on success/failure to populate with buffers, and zx.Status
1777 /// on failure. In that case, `has_constraints` can be false, and
1778 /// `constraints` will be ignored.
1779 ///
1780 /// VMO handles will not be provided to the client that sends null
1781 /// constraints - that can be intentional for an initiator that doesn't need
1782 /// VMO handles. Not having VMO handles doesn't prevent the initator from
1783 /// adjusting which portion of a buffer is considered valid and similar, but
1784 /// the initiator can't hold a VMO handle open to prevent the logical
1785 /// BufferCollection from cleaning up if the logical BufferCollection needs
1786 /// to go away regardless of the initiator's degree of involvement for
1787 /// whatever reason.
1788 ///
1789 /// For population of buffers to be attempted, all holders of a
1790 /// BufferCollection client channel need to call SetConstraints() before
1791 /// sysmem will attempt to allocate buffers.
1792 ///
1793 /// `has_constraints` if false, the constraints are effectively null, and
1794 /// `constraints` are ignored. The sender of null constraints won't get any
1795 /// VMO handles in BufferCollectionInfo, but can still find out how many
1796 /// buffers were allocated and can still refer to buffers by their
1797 /// buffer_index.
1798 ///
1799 /// `constraints` are constraints on the buffer collection.
1800 pub fn r#set_constraints(
1801 &self,
1802 mut has_constraints: bool,
1803 mut constraints: &BufferCollectionConstraints,
1804 ) -> Result<(), fidl::Error> {
1805 self.client.send::<BufferCollectionSetConstraintsRequest>(
1806 (has_constraints, constraints),
1807 0x4d9c3406c213227b,
1808 fidl::encoding::DynamicFlags::empty(),
1809 )
1810 }
1811
1812 /// This request completes when buffers have been allocated, responds with
1813 /// some failure detail if allocation has been attempted but failed.
1814 ///
1815 /// The following must occur before buffers will be allocated:
1816 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
1817 /// must be turned in via BindSharedCollection().
1818 /// * All BufferCollection(s) of the logical BufferCollection must have
1819 /// had SetConstraints() sent to them.
1820 ///
1821 /// Returns `ZX_OK` if successful.
1822 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
1823 /// fulfilled due to resource exhaustion.
1824 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
1825 /// obtain the buffers it requested.
1826 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
1827 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
1828 /// satisfied, perhaps due to hardware limitations.
1829 ///
1830 /// `buffer_collection_info` has the VMO handles and other related info.
1831 pub fn r#wait_for_buffers_allocated(
1832 &self,
1833 ___deadline: zx::MonotonicInstant,
1834 ) -> Result<(i32, BufferCollectionInfo2), fidl::Error> {
1835 let _response = self.client.send_query::<
1836 fidl::encoding::EmptyPayload,
1837 BufferCollectionWaitForBuffersAllocatedResponse,
1838 BufferCollectionMarker,
1839 >(
1840 (),
1841 0x714667ea2a29a3a2,
1842 fidl::encoding::DynamicFlags::empty(),
1843 ___deadline,
1844 )?;
1845 Ok((_response.status, _response.buffer_collection_info))
1846 }
1847
1848 /// This returns the same result code as WaitForBuffersAllocated if the
1849 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
1850 /// if WaitForBuffersAllocated would block.
1851 pub fn r#check_buffers_allocated(
1852 &self,
1853 ___deadline: zx::MonotonicInstant,
1854 ) -> Result<i32, fidl::Error> {
1855 let _response = self.client.send_query::<
1856 fidl::encoding::EmptyPayload,
1857 BufferCollectionCheckBuffersAllocatedResponse,
1858 BufferCollectionMarker,
1859 >(
1860 (),
1861 0x245bb81f79189e9,
1862 fidl::encoding::DynamicFlags::empty(),
1863 ___deadline,
1864 )?;
1865 Ok(_response.status)
1866 }
1867
1868 /// Create a new token, for trying to add a new participant to an existing
1869 /// collection, if the existing collection's buffer counts, constraints,
1870 /// and participants allow.
1871 ///
1872 /// This can be useful in replacing a failed participant, and/or in
1873 /// adding/re-adding a participant after buffers have already been
1874 /// allocated.
1875 ///
1876 /// Failure of an attached token / collection does not propagate to the
1877 /// parent of the attached token. Failure does propagate from a normal
1878 /// child of a dispensable token to the dispensable token. Failure
1879 /// of a child is blocked from reaching its parent if the child is attached,
1880 /// or if the child is dispensable and the failure occurred after logical
1881 /// allocation.
1882 ///
1883 /// An initiator may in some scenarios choose to initially use a dispensable
1884 /// token for a given instance of a participant, and then later if the first
1885 /// instance of that participant fails, a new second instance of that
1886 /// participant my be given a token created with AttachToken().
1887 ///
1888 /// From the point of view of the client end of the BufferCollectionToken
1889 /// channel, the token acts like any other token. The client can
1890 /// Duplicate() the token as needed, and can send the token to a different
1891 /// process. The token should be converted to a BufferCollection channel
1892 /// as normal by calling BindSharedCollection(). SetConstraints() should
1893 /// be called on that BufferCollection channel.
1894 ///
1895 /// A success result from WaitForBuffersAllocated() means the new
1896 /// participant's constraints were satisfiable using the already-existing
1897 /// buffer collection, the already-established BufferCollectionInfo
1898 /// including image format constraints, and the already-existing other
1899 /// participants and their buffer counts. A failure result means the new
1900 /// participant's constraints cannot be satisfied using the existing
1901 /// buffer collection and its already-logically-allocated participants.
1902 /// Creating a new collection instead may allow all participant's
1903 /// constraints to be satisfied, assuming SetDispensable() is used in place
1904 /// of AttachToken(), or a normal token is used.
1905 ///
1906 /// A token created with AttachToken() performs constraints aggregation with
1907 /// all constraints currently in effect on the buffer collection, plus the
1908 /// attached token under consideration plus child tokens under the attached
1909 /// token which are not themselves an attached token or under such a token.
1910 ///
1911 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
1912 /// first-come first-served, but a child can't logically allocate before
1913 /// all its parents have sent SetConstraints().
1914 ///
1915 /// See also SetDispensable(), which in contrast to AttachToken(), has the
1916 /// created token + children participate in constraints aggregation along
1917 /// with its parent.
1918 ///
1919 /// The newly created token needs to be Sync()ed to sysmem before the new
1920 /// token can be passed to BindSharedCollection(). The Sync() of the new
1921 /// token can be accomplished with BufferCollection.Sync() on this
1922 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
1923 /// token also works. A BufferCollectionToken.Sync() can be started after
1924 /// any BufferCollectionToken.Duplicate() messages have been sent via the
1925 /// newly created token, to also sync those additional tokens to sysmem
1926 /// using a single round-trip.
1927 ///
1928 /// These values for rights_attenuation_mask result in no attenuation (note
1929 /// that 0 is not on this list; 0 will output an ERROR to the system log
1930 /// to help diagnose the bug in client code):
1931 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
1932 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
1933 pub fn r#attach_token(
1934 &self,
1935 mut rights_attenuation_mask: u32,
1936 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
1937 ) -> Result<(), fidl::Error> {
1938 self.client.send::<BufferCollectionAttachTokenRequest>(
1939 (rights_attenuation_mask, token_request),
1940 0x6f5adcca4ac7443e,
1941 fidl::encoding::DynamicFlags::empty(),
1942 )
1943 }
1944
1945 /// AttachLifetimeTracking:
1946 ///
1947 /// AttachLifetimeTracking() is intended to allow a client to wait until an
1948 /// old logical buffer collection is fully or mostly deallocated before
1949 /// attempting allocation of a new logical buffer collection.
1950 ///
1951 /// Attach an eventpair endpoint to the logical buffer collection, so that
1952 /// the server_end will be closed when the number of buffers allocated
1953 /// drops to 'buffers_remaining'. The server_end won't close until after
1954 /// logical allocation has completed.
1955 ///
1956 /// If logical allocation fails, such as for an attached sub-tree (using
1957 /// AttachToken()), the server_end will close during that failure regardless
1958 /// of the number of buffers potenitally allocated in the overall logical
1959 /// buffer collection.
1960 ///
1961 /// The lifetime signalled by this event includes asynchronous cleanup of
1962 /// allocated buffers, and this asynchronous cleanup cannot occur until all
1963 /// holders of VMO handles to the buffers have closed those VMO handles.
1964 /// Therefore clients should take care not to become blocked forever waiting
1965 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
1966 /// participants using the logical buffer collection are less trusted or
1967 /// less reliable.
1968 ///
1969 /// The buffers_remaining parameter allows waiting for all but
1970 /// buffers_remaining buffers to be fully deallocated. This can be useful
1971 /// in situations where a known number of buffers are intentionally not
1972 /// closed so that the data can continue to be used, such as for keeping the
1973 /// last available video picture displayed in the UI even if the video
1974 /// stream was using protected output buffers. It's outside the scope of
1975 /// the BufferCollection interface (at least for now) to determine how many
1976 /// buffers may be held without closing, but it'll typically be in the range
1977 /// 0-2.
1978 ///
1979 /// This mechanism is meant to be compatible with other protocols providing
1980 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
1981 /// same event can be sent to more than one AttachLifetimeTracking(), and
1982 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
1983 /// over conditions are met (all holders of duplicates have closed their
1984 /// handle(s)).
1985 ///
1986 /// There is no way to cancel an attach. Closing the client end of the
1987 /// eventpair doesn't subtract from the number of pending attach(es).
1988 ///
1989 /// Closing the client's end doesn't result in any action by the server.
1990 /// If the server listens to events from the client end at all, it is for
1991 /// debug logging only.
1992 ///
1993 /// The server intentionally doesn't "trust" any bits signalled by the
1994 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
1995 /// which can't be triggered early, and is only triggered when all handles
1996 /// to server_end are closed. No meaning is associated with any of the
1997 /// other signal bits, and clients should functionally ignore any other
1998 /// signal bits on either end of the eventpair or its peer.
1999 ///
2000 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
2001 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
2002 /// transfer without causing CodecFactory channel failure).
2003 pub fn r#attach_lifetime_tracking(
2004 &self,
2005 mut server_end: fidl::EventPair,
2006 mut buffers_remaining: u32,
2007 ) -> Result<(), fidl::Error> {
2008 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
2009 (server_end, buffers_remaining),
2010 0x170d0f1d89d50989,
2011 fidl::encoding::DynamicFlags::empty(),
2012 )
2013 }
2014}
2015
2016#[cfg(target_os = "fuchsia")]
2017impl From<BufferCollectionSynchronousProxy> for zx::NullableHandle {
2018 fn from(value: BufferCollectionSynchronousProxy) -> Self {
2019 value.into_channel().into()
2020 }
2021}
2022
2023#[cfg(target_os = "fuchsia")]
2024impl From<fidl::Channel> for BufferCollectionSynchronousProxy {
2025 fn from(value: fidl::Channel) -> Self {
2026 Self::new(value)
2027 }
2028}
2029
2030#[cfg(target_os = "fuchsia")]
2031impl fidl::endpoints::FromClient for BufferCollectionSynchronousProxy {
2032 type Protocol = BufferCollectionMarker;
2033
2034 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionMarker>) -> Self {
2035 Self::new(value.into_channel())
2036 }
2037}
2038
2039#[derive(Debug, Clone)]
2040pub struct BufferCollectionProxy {
2041 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
2042}
2043
2044impl fidl::endpoints::Proxy for BufferCollectionProxy {
2045 type Protocol = BufferCollectionMarker;
2046
2047 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
2048 Self::new(inner)
2049 }
2050
2051 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
2052 self.client.into_channel().map_err(|client| Self { client })
2053 }
2054
2055 fn as_channel(&self) -> &::fidl::AsyncChannel {
2056 self.client.as_channel()
2057 }
2058}
2059
2060impl BufferCollectionProxy {
2061 /// Create a new Proxy for fuchsia.sysmem/BufferCollection.
2062 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
2063 let protocol_name = <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
2064 Self { client: fidl::client::Client::new(channel, protocol_name) }
2065 }
2066
2067 /// Get a Stream of events from the remote end of the protocol.
2068 ///
2069 /// # Panics
2070 ///
2071 /// Panics if the event stream was already taken.
2072 pub fn take_event_stream(&self) -> BufferCollectionEventStream {
2073 BufferCollectionEventStream { event_receiver: self.client.take_event_receiver() }
2074 }
2075
2076 /// Ensure that previous messages, including Duplicate() messages on a
2077 /// token, collection, or group, have been received server side.
2078 ///
2079 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
2080 /// valid sysmem token risks the Sync() hanging forever. See
2081 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
2082 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
2083 /// Another way is to pass the token to BindSharedCollection(), which also
2084 /// validates the token as part of exchanging it for a BufferCollection
2085 /// channel, and BufferCollection Sync() can then be used.
2086 ///
2087 /// After a Sync(), it's then safe to send the client end of token_request
2088 /// to another participant knowing the server will recognize the token when
2089 /// it's sent into BindSharedCollection() by the other participant.
2090 ///
2091 /// Other options include waiting for each token.Duplicate() to complete
2092 /// individually (using separate call to token.Sync() after each), or
2093 /// calling Sync() on BufferCollection after the token has been turned in
2094 /// via BindSharedCollection().
2095 ///
2096 /// Another way to mitigate is to avoid calling Sync() on the token, and
2097 /// instead later deal with potential failure of BufferCollection.Sync() if
2098 /// the original token was invalid. This option can be preferable from a
2099 /// performance point of view, but requires client code to delay sending
2100 /// tokens duplicated from this token until after client code has converted
2101 /// the duplicating token to a BufferCollection and received successful
2102 /// response from BufferCollection.Sync().
2103 ///
2104 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
2105 /// When BufferCollection.Sync() isn't feasible, the caller must already
2106 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
2107 /// hang forever. See ValidateBufferCollectionToken() to check token
2108 /// validity first if the token isn't already known to be (is/was) valid.
2109 pub fn r#sync(
2110 &self,
2111 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
2112 BufferCollectionProxyInterface::r#sync(self)
2113 }
2114
2115 /// On a BufferCollectionToken channel:
2116 ///
2117 /// Normally a participant will convert a BufferCollectionToken into a
2118 /// BufferCollection view, but a participant is also free to Close() the
2119 /// token (and then close the channel immediately or shortly later in
2120 /// response to server closing its end), which avoids causing logical buffer
2121 /// collection failure. Â Normally an unexpected token channel close will
2122 /// cause logical buffer collection failure (the only exceptions being
2123 /// certain cases involving AttachToken() or SetDispensable()).
2124 ///
2125 /// On a BufferCollection channel:
2126 ///
2127 /// By default the server handles unexpected failure of a BufferCollection
2128 /// by failing the whole logical buffer collection. Partly this is to
2129 /// expedite closing VMO handles to reclaim memory when any participant
2130 /// fails. If a participant would like to cleanly close a BufferCollection
2131 /// view without causing logical buffer collection failure, the participant
2132 /// can send Close() before closing the client end of the BufferCollection
2133 /// channel. If this is the last BufferCollection view, the logical buffer
2134 /// collection will still go away. The Close() can occur before or after
2135 /// SetConstraints(). If before SetConstraints(), the buffer collection
2136 /// won't require constraints from this node in order to allocate. If
2137 /// after SetConstraints(), the constraints are retained and aggregated
2138 /// along with any subsequent logical allocation(s), despite the lack of
2139 /// channel connection.
2140 ///
2141 /// On a BufferCollectionTokenGroup channel:
2142 ///
2143 /// By default, unexpected failure of a BufferCollectionTokenGroup will
2144 /// trigger failure of the logical BufferCollectionTokenGroup and will
2145 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
2146 /// channel without failing the logical group or propagating failure, send
2147 /// Close() before closing the channel client endpoint.
2148 ///
2149 /// If Close() occurs before AllChildrenPresent(), the logical buffer
2150 /// collection will still fail despite the Close() (because sysmem can't be
2151 /// sure whether all relevant children were created, so it's ambiguous
2152 /// whether all relevant constraints will be provided to sysmem). If
2153 /// Close() occurs after AllChildrenPresent(), the children and all their
2154 /// constraints remain intact (just as they would if the
2155 /// BufferCollectionTokenGroup channel had remained open), and the close
2156 /// doesn't trigger or propagate failure.
2157 pub fn r#close(&self) -> Result<(), fidl::Error> {
2158 BufferCollectionProxyInterface::r#close(self)
2159 }
2160
2161 /// Set a name for VMOs in this buffer collection. The name may be truncated
2162 /// shorter. The name only affects VMOs allocated after it's set - this call
2163 /// does not rename existing VMOs. If multiple clients set different names
2164 /// then the larger priority value will win.
2165 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
2166 BufferCollectionProxyInterface::r#set_name(self, priority, name)
2167 }
2168
2169 /// Set information about the current client that can be used by sysmem to
2170 /// help debug leaking memory and hangs waiting for constraints. |name| can
2171 /// be an arbitrary string, but the current process name (see
2172 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
2173 /// arbitrary id, but the current process ID (see
2174 /// fsl::GetCurrentProcessKoid()) is a good default.
2175 ///
2176 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
2177 /// indicate which client is closing their channel first, leading to
2178 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
2179 /// over, but if happening earlier than expected, the
2180 /// client-channel-specific name can help diagnose where the failure is
2181 /// first coming from, from sysmem's point of view).
2182 ///
2183 /// By default (unless overriden by this message or using
2184 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
2185 /// parent Node at the time the child Node is created. While this can be
2186 /// better than nothing, it's often better for each participant to use
2187 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
2188 /// info directly relevant to the current client. Also, SetVerboseLogging()
2189 /// can be used to help disambiguate if a Node is suspected of having info
2190 /// that was copied from its parent.
2191 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
2192 BufferCollectionProxyInterface::r#set_debug_client_info(self, name, id)
2193 }
2194
2195 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
2196 /// after creating a collection. Clients can call this method to change
2197 /// when the log is printed. If multiple client set the deadline, it's
2198 /// unspecified which deadline will take effect.
2199 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
2200 BufferCollectionProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
2201 }
2202
2203 /// Verbose logging includes constraints set via SetConstraints() from each
2204 /// client along with info set via SetDebugClientInfo() and the structure of
2205 /// the tree of Node(s).
2206 ///
2207 /// Normally sysmem prints only a single line complaint when aggregation
2208 /// fails, with just the specific detailed reason that aggregation failed,
2209 /// with minimal context. While this is often enough to diagnose a problem
2210 /// if only a small change was made and the system had been working before
2211 /// the small change, it's often not particularly helpful for getting a new
2212 /// buffer collection to work for the first time. Especially with more
2213 /// complex trees of nodes, involving things like AttachToken(),
2214 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
2215 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
2216 /// looks like and why it's failing a logical allocation, or why a tree or
2217 /// sub-tree is failing sooner than expected.
2218 ///
2219 /// The intent of the extra logging is to be acceptable from a performance
2220 /// point of view, if only enabled on a low number of buffer collections.
2221 /// If we're not tracking down a bug, we shouldn't send this message.
2222 ///
2223 /// If too many participants leave verbose logging enabled, we may end up
2224 /// needing to require that system-wide sysmem verbose logging be permitted
2225 /// via some other setting, to avoid sysmem spamming the log too much due to
2226 /// this message.
2227 ///
2228 /// This may be a NOP for some nodes due to intentional policy associated
2229 /// with the node, if we don't trust a node enough to let it turn on verbose
2230 /// logging.
2231 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
2232 BufferCollectionProxyInterface::r#set_verbose_logging(self)
2233 }
2234
2235 /// This gets an event handle that can be used as a parameter to
2236 /// IsAlternateFor() called on any Node. The client will not be granted the
2237 /// right to signal this event, as this handle should only be used as proof
2238 /// that the client obtained this handle from this Node.
2239 ///
2240 /// Because this is a get not a set, no Sync() is needed between the
2241 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
2242 /// potentially being on different channels.
2243 ///
2244 /// See also IsAlternateFor().
2245 pub fn r#get_node_ref(
2246 &self,
2247 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
2248 {
2249 BufferCollectionProxyInterface::r#get_node_ref(self)
2250 }
2251
2252 /// This checks whether the calling node is in a subtree rooted at a
2253 /// different child token of a common parent BufferCollectionTokenGroup, in
2254 /// relation to the passed-in node_ref.
2255 ///
2256 /// This call is for assisting with admission control de-duplication, and
2257 /// with debugging.
2258 ///
2259 /// The node_ref must be obtained using GetNodeRef() of a
2260 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
2261 ///
2262 /// The node_ref can be a duplicated handle; it's not necessary to call
2263 /// GetNodeRef() for every call to IsAlternateFor().
2264 ///
2265 /// If a calling token may not actually be a valid token at all due to
2266 /// a potentially hostile/untrusted provider of the token, call
2267 /// ValidateBufferCollectionToken() first instead of potentially getting
2268 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
2269 /// token not being a real token (not really talking to sysmem). Another
2270 /// option is to call BindSharedCollection with this token first which also
2271 /// validates the token along with converting it to a BufferCollection, then
2272 /// call BufferCollection IsAlternateFor().
2273 ///
2274 /// error values:
2275 ///
2276 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
2277 /// buffer collection as the calling Node. Before logical allocation and
2278 /// within the same logical allocation sub-tree, this essentially means that
2279 /// the node_ref was never part of this logical buffer collection, since
2280 /// before logical allocation all node_refs that come into existence remain
2281 /// in existence at least until logical allocation (including Node(s) that
2282 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
2283 /// to be returned, this Node's channel needs to still be connected server
2284 /// side, which won't be the case if the whole logical allocation has
2285 /// failed. After logical allocation or in a different logical allocation
2286 /// sub-tree there are additional potential reasons for this error. For
2287 /// example a different logical allocation (separated from this Node(s)
2288 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
2289 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
2290 /// exist and may select a different child sub-tree than the sub-tree the
2291 /// node_ref is in causing deletion of the node_ref Node. The only time
2292 /// sysmem keeps a Node around after that Node has no corresponding channel
2293 /// is when Close() is used and the Node's sub-tree has not yet failed.
2294 /// Another reason for this error is if the node_ref is an eventpair handle
2295 /// with sufficient rights, but isn't actually a real node_ref obtained from
2296 /// GetNodeRef().
2297 ///
2298 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
2299 /// eventpair handle, or doesn't have the needed rights expected on a real
2300 /// node_ref.
2301 ///
2302 /// No other failing status codes are returned by this call. However,
2303 /// sysmem may add additional codes in future, so the client should have
2304 /// sensible default handling for any failing status code.
2305 ///
2306 /// On success, is_alternate has the following meaning:
2307 /// * true - The first parent node in common between the calling node and
2308 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
2309 /// the calling Node and the node_ref Node will _not_ have both their
2310 /// constraints apply - rather sysmem will choose one or the other of
2311 /// the constraints - never both. This is because only one child of
2312 /// a BufferCollectionTokenGroup is selected during logical allocation,
2313 /// with only that one child's sub-tree contributing to constraints
2314 /// aggregation.
2315 /// * false - The first parent node in common between the calling Node and
2316 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
2317 /// this means the first parent node in common is a
2318 /// BufferCollectionToken or BufferCollection (regardless of not
2319 /// Close()ed or Close()ed). This means that the calling Node and the
2320 /// node_ref Node _may_ have both their constraints apply during
2321 /// constraints aggregation of the logical allocation, if both Node(s)
2322 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
2323 /// In this case, there is no BufferCollectionTokenGroup that will
2324 /// directly prevent the two Node(s) from both being selected and their
2325 /// constraints both aggregated, but even when false, one or both
2326 /// Node(s) may still be eliminated from consideration if one or both
2327 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
2328 /// which selects a child sub-tree other than the sub-tree containing
2329 /// the calling Node or node_ref Node.
2330 pub fn r#is_alternate_for(
2331 &self,
2332 mut node_ref: fidl::Event,
2333 ) -> fidl::client::QueryResponseFut<
2334 NodeIsAlternateForResult,
2335 fidl::encoding::DefaultFuchsiaResourceDialect,
2336 > {
2337 BufferCollectionProxyInterface::r#is_alternate_for(self, node_ref)
2338 }
2339
2340 /// Provide BufferCollectionConstraints to the logical BufferCollection.
2341 ///
2342 /// A participant may only call SetConstraints() once.
2343 ///
2344 /// Sometimes the initiator is a participant only in the sense of wanting to
2345 /// keep an eye on success/failure to populate with buffers, and zx.Status
2346 /// on failure. In that case, `has_constraints` can be false, and
2347 /// `constraints` will be ignored.
2348 ///
2349 /// VMO handles will not be provided to the client that sends null
2350 /// constraints - that can be intentional for an initiator that doesn't need
2351 /// VMO handles. Not having VMO handles doesn't prevent the initator from
2352 /// adjusting which portion of a buffer is considered valid and similar, but
2353 /// the initiator can't hold a VMO handle open to prevent the logical
2354 /// BufferCollection from cleaning up if the logical BufferCollection needs
2355 /// to go away regardless of the initiator's degree of involvement for
2356 /// whatever reason.
2357 ///
2358 /// For population of buffers to be attempted, all holders of a
2359 /// BufferCollection client channel need to call SetConstraints() before
2360 /// sysmem will attempt to allocate buffers.
2361 ///
2362 /// `has_constraints` if false, the constraints are effectively null, and
2363 /// `constraints` are ignored. The sender of null constraints won't get any
2364 /// VMO handles in BufferCollectionInfo, but can still find out how many
2365 /// buffers were allocated and can still refer to buffers by their
2366 /// buffer_index.
2367 ///
2368 /// `constraints` are constraints on the buffer collection.
2369 pub fn r#set_constraints(
2370 &self,
2371 mut has_constraints: bool,
2372 mut constraints: &BufferCollectionConstraints,
2373 ) -> Result<(), fidl::Error> {
2374 BufferCollectionProxyInterface::r#set_constraints(self, has_constraints, constraints)
2375 }
2376
2377 /// This request completes when buffers have been allocated, responds with
2378 /// some failure detail if allocation has been attempted but failed.
2379 ///
2380 /// The following must occur before buffers will be allocated:
2381 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
2382 /// must be turned in via BindSharedCollection().
2383 /// * All BufferCollection(s) of the logical BufferCollection must have
2384 /// had SetConstraints() sent to them.
2385 ///
2386 /// Returns `ZX_OK` if successful.
2387 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
2388 /// fulfilled due to resource exhaustion.
2389 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
2390 /// obtain the buffers it requested.
2391 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
2392 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
2393 /// satisfied, perhaps due to hardware limitations.
2394 ///
2395 /// `buffer_collection_info` has the VMO handles and other related info.
2396 pub fn r#wait_for_buffers_allocated(
2397 &self,
2398 ) -> fidl::client::QueryResponseFut<
2399 (i32, BufferCollectionInfo2),
2400 fidl::encoding::DefaultFuchsiaResourceDialect,
2401 > {
2402 BufferCollectionProxyInterface::r#wait_for_buffers_allocated(self)
2403 }
2404
2405 /// This returns the same result code as WaitForBuffersAllocated if the
2406 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
2407 /// if WaitForBuffersAllocated would block.
2408 pub fn r#check_buffers_allocated(
2409 &self,
2410 ) -> fidl::client::QueryResponseFut<i32, fidl::encoding::DefaultFuchsiaResourceDialect> {
2411 BufferCollectionProxyInterface::r#check_buffers_allocated(self)
2412 }
2413
2414 /// Create a new token, for trying to add a new participant to an existing
2415 /// collection, if the existing collection's buffer counts, constraints,
2416 /// and participants allow.
2417 ///
2418 /// This can be useful in replacing a failed participant, and/or in
2419 /// adding/re-adding a participant after buffers have already been
2420 /// allocated.
2421 ///
2422 /// Failure of an attached token / collection does not propagate to the
2423 /// parent of the attached token. Failure does propagate from a normal
2424 /// child of a dispensable token to the dispensable token. Failure
2425 /// of a child is blocked from reaching its parent if the child is attached,
2426 /// or if the child is dispensable and the failure occurred after logical
2427 /// allocation.
2428 ///
2429 /// An initiator may in some scenarios choose to initially use a dispensable
2430 /// token for a given instance of a participant, and then later if the first
2431 /// instance of that participant fails, a new second instance of that
2432 /// participant my be given a token created with AttachToken().
2433 ///
2434 /// From the point of view of the client end of the BufferCollectionToken
2435 /// channel, the token acts like any other token. The client can
2436 /// Duplicate() the token as needed, and can send the token to a different
2437 /// process. The token should be converted to a BufferCollection channel
2438 /// as normal by calling BindSharedCollection(). SetConstraints() should
2439 /// be called on that BufferCollection channel.
2440 ///
2441 /// A success result from WaitForBuffersAllocated() means the new
2442 /// participant's constraints were satisfiable using the already-existing
2443 /// buffer collection, the already-established BufferCollectionInfo
2444 /// including image format constraints, and the already-existing other
2445 /// participants and their buffer counts. A failure result means the new
2446 /// participant's constraints cannot be satisfied using the existing
2447 /// buffer collection and its already-logically-allocated participants.
2448 /// Creating a new collection instead may allow all participant's
2449 /// constraints to be satisfied, assuming SetDispensable() is used in place
2450 /// of AttachToken(), or a normal token is used.
2451 ///
2452 /// A token created with AttachToken() performs constraints aggregation with
2453 /// all constraints currently in effect on the buffer collection, plus the
2454 /// attached token under consideration plus child tokens under the attached
2455 /// token which are not themselves an attached token or under such a token.
2456 ///
2457 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
2458 /// first-come first-served, but a child can't logically allocate before
2459 /// all its parents have sent SetConstraints().
2460 ///
2461 /// See also SetDispensable(), which in contrast to AttachToken(), has the
2462 /// created token + children participate in constraints aggregation along
2463 /// with its parent.
2464 ///
2465 /// The newly created token needs to be Sync()ed to sysmem before the new
2466 /// token can be passed to BindSharedCollection(). The Sync() of the new
2467 /// token can be accomplished with BufferCollection.Sync() on this
2468 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
2469 /// token also works. A BufferCollectionToken.Sync() can be started after
2470 /// any BufferCollectionToken.Duplicate() messages have been sent via the
2471 /// newly created token, to also sync those additional tokens to sysmem
2472 /// using a single round-trip.
2473 ///
2474 /// These values for rights_attenuation_mask result in no attenuation (note
2475 /// that 0 is not on this list; 0 will output an ERROR to the system log
2476 /// to help diagnose the bug in client code):
2477 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
2478 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
2479 pub fn r#attach_token(
2480 &self,
2481 mut rights_attenuation_mask: u32,
2482 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
2483 ) -> Result<(), fidl::Error> {
2484 BufferCollectionProxyInterface::r#attach_token(self, rights_attenuation_mask, token_request)
2485 }
2486
2487 /// AttachLifetimeTracking:
2488 ///
2489 /// AttachLifetimeTracking() is intended to allow a client to wait until an
2490 /// old logical buffer collection is fully or mostly deallocated before
2491 /// attempting allocation of a new logical buffer collection.
2492 ///
2493 /// Attach an eventpair endpoint to the logical buffer collection, so that
2494 /// the server_end will be closed when the number of buffers allocated
2495 /// drops to 'buffers_remaining'. The server_end won't close until after
2496 /// logical allocation has completed.
2497 ///
2498 /// If logical allocation fails, such as for an attached sub-tree (using
2499 /// AttachToken()), the server_end will close during that failure regardless
2500 /// of the number of buffers potenitally allocated in the overall logical
2501 /// buffer collection.
2502 ///
2503 /// The lifetime signalled by this event includes asynchronous cleanup of
2504 /// allocated buffers, and this asynchronous cleanup cannot occur until all
2505 /// holders of VMO handles to the buffers have closed those VMO handles.
2506 /// Therefore clients should take care not to become blocked forever waiting
2507 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
2508 /// participants using the logical buffer collection are less trusted or
2509 /// less reliable.
2510 ///
2511 /// The buffers_remaining parameter allows waiting for all but
2512 /// buffers_remaining buffers to be fully deallocated. This can be useful
2513 /// in situations where a known number of buffers are intentionally not
2514 /// closed so that the data can continue to be used, such as for keeping the
2515 /// last available video picture displayed in the UI even if the video
2516 /// stream was using protected output buffers. It's outside the scope of
2517 /// the BufferCollection interface (at least for now) to determine how many
2518 /// buffers may be held without closing, but it'll typically be in the range
2519 /// 0-2.
2520 ///
2521 /// This mechanism is meant to be compatible with other protocols providing
2522 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
2523 /// same event can be sent to more than one AttachLifetimeTracking(), and
2524 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
2525 /// over conditions are met (all holders of duplicates have closed their
2526 /// handle(s)).
2527 ///
2528 /// There is no way to cancel an attach. Closing the client end of the
2529 /// eventpair doesn't subtract from the number of pending attach(es).
2530 ///
2531 /// Closing the client's end doesn't result in any action by the server.
2532 /// If the server listens to events from the client end at all, it is for
2533 /// debug logging only.
2534 ///
2535 /// The server intentionally doesn't "trust" any bits signalled by the
2536 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
2537 /// which can't be triggered early, and is only triggered when all handles
2538 /// to server_end are closed. No meaning is associated with any of the
2539 /// other signal bits, and clients should functionally ignore any other
2540 /// signal bits on either end of the eventpair or its peer.
2541 ///
2542 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
2543 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
2544 /// transfer without causing CodecFactory channel failure).
2545 pub fn r#attach_lifetime_tracking(
2546 &self,
2547 mut server_end: fidl::EventPair,
2548 mut buffers_remaining: u32,
2549 ) -> Result<(), fidl::Error> {
2550 BufferCollectionProxyInterface::r#attach_lifetime_tracking(
2551 self,
2552 server_end,
2553 buffers_remaining,
2554 )
2555 }
2556}
2557
2558impl BufferCollectionProxyInterface for BufferCollectionProxy {
2559 type SyncResponseFut =
2560 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
2561 fn r#sync(&self) -> Self::SyncResponseFut {
2562 fn _decode(
2563 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2564 ) -> Result<(), fidl::Error> {
2565 let _response = fidl::client::decode_transaction_body::<
2566 fidl::encoding::EmptyPayload,
2567 fidl::encoding::DefaultFuchsiaResourceDialect,
2568 0x4577e238ae26291,
2569 >(_buf?)?;
2570 Ok(_response)
2571 }
2572 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
2573 (),
2574 0x4577e238ae26291,
2575 fidl::encoding::DynamicFlags::empty(),
2576 _decode,
2577 )
2578 }
2579
2580 fn r#close(&self) -> Result<(), fidl::Error> {
2581 self.client.send::<fidl::encoding::EmptyPayload>(
2582 (),
2583 0x5b1d7a4f5681fca7,
2584 fidl::encoding::DynamicFlags::empty(),
2585 )
2586 }
2587
2588 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
2589 self.client.send::<NodeSetNameRequest>(
2590 (priority, name),
2591 0x77a41bb6217e2443,
2592 fidl::encoding::DynamicFlags::empty(),
2593 )
2594 }
2595
2596 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
2597 self.client.send::<NodeSetDebugClientInfoRequest>(
2598 (name, id),
2599 0x7275759070eb5ee2,
2600 fidl::encoding::DynamicFlags::empty(),
2601 )
2602 }
2603
2604 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
2605 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
2606 (deadline,),
2607 0x46d38f4772638867,
2608 fidl::encoding::DynamicFlags::empty(),
2609 )
2610 }
2611
2612 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
2613 self.client.send::<fidl::encoding::EmptyPayload>(
2614 (),
2615 0x6bfbe2cf1701d288,
2616 fidl::encoding::DynamicFlags::empty(),
2617 )
2618 }
2619
2620 type GetNodeRefResponseFut =
2621 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
2622 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
2623 fn _decode(
2624 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2625 ) -> Result<fidl::Event, fidl::Error> {
2626 let _response = fidl::client::decode_transaction_body::<
2627 NodeGetNodeRefResponse,
2628 fidl::encoding::DefaultFuchsiaResourceDialect,
2629 0x467b7c75c35c3b84,
2630 >(_buf?)?;
2631 Ok(_response.node_ref)
2632 }
2633 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
2634 (),
2635 0x467b7c75c35c3b84,
2636 fidl::encoding::DynamicFlags::empty(),
2637 _decode,
2638 )
2639 }
2640
2641 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
2642 NodeIsAlternateForResult,
2643 fidl::encoding::DefaultFuchsiaResourceDialect,
2644 >;
2645 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
2646 fn _decode(
2647 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2648 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
2649 let _response = fidl::client::decode_transaction_body::<
2650 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
2651 fidl::encoding::DefaultFuchsiaResourceDialect,
2652 0x33a2a7aff2776c07,
2653 >(_buf?)?;
2654 Ok(_response.map(|x| x.is_alternate))
2655 }
2656 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
2657 (node_ref,),
2658 0x33a2a7aff2776c07,
2659 fidl::encoding::DynamicFlags::empty(),
2660 _decode,
2661 )
2662 }
2663
2664 fn r#set_constraints(
2665 &self,
2666 mut has_constraints: bool,
2667 mut constraints: &BufferCollectionConstraints,
2668 ) -> Result<(), fidl::Error> {
2669 self.client.send::<BufferCollectionSetConstraintsRequest>(
2670 (has_constraints, constraints),
2671 0x4d9c3406c213227b,
2672 fidl::encoding::DynamicFlags::empty(),
2673 )
2674 }
2675
2676 type WaitForBuffersAllocatedResponseFut = fidl::client::QueryResponseFut<
2677 (i32, BufferCollectionInfo2),
2678 fidl::encoding::DefaultFuchsiaResourceDialect,
2679 >;
2680 fn r#wait_for_buffers_allocated(&self) -> Self::WaitForBuffersAllocatedResponseFut {
2681 fn _decode(
2682 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2683 ) -> Result<(i32, BufferCollectionInfo2), fidl::Error> {
2684 let _response = fidl::client::decode_transaction_body::<
2685 BufferCollectionWaitForBuffersAllocatedResponse,
2686 fidl::encoding::DefaultFuchsiaResourceDialect,
2687 0x714667ea2a29a3a2,
2688 >(_buf?)?;
2689 Ok((_response.status, _response.buffer_collection_info))
2690 }
2691 self.client
2692 .send_query_and_decode::<fidl::encoding::EmptyPayload, (i32, BufferCollectionInfo2)>(
2693 (),
2694 0x714667ea2a29a3a2,
2695 fidl::encoding::DynamicFlags::empty(),
2696 _decode,
2697 )
2698 }
2699
2700 type CheckBuffersAllocatedResponseFut =
2701 fidl::client::QueryResponseFut<i32, fidl::encoding::DefaultFuchsiaResourceDialect>;
2702 fn r#check_buffers_allocated(&self) -> Self::CheckBuffersAllocatedResponseFut {
2703 fn _decode(
2704 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2705 ) -> Result<i32, fidl::Error> {
2706 let _response = fidl::client::decode_transaction_body::<
2707 BufferCollectionCheckBuffersAllocatedResponse,
2708 fidl::encoding::DefaultFuchsiaResourceDialect,
2709 0x245bb81f79189e9,
2710 >(_buf?)?;
2711 Ok(_response.status)
2712 }
2713 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, i32>(
2714 (),
2715 0x245bb81f79189e9,
2716 fidl::encoding::DynamicFlags::empty(),
2717 _decode,
2718 )
2719 }
2720
2721 fn r#attach_token(
2722 &self,
2723 mut rights_attenuation_mask: u32,
2724 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
2725 ) -> Result<(), fidl::Error> {
2726 self.client.send::<BufferCollectionAttachTokenRequest>(
2727 (rights_attenuation_mask, token_request),
2728 0x6f5adcca4ac7443e,
2729 fidl::encoding::DynamicFlags::empty(),
2730 )
2731 }
2732
2733 fn r#attach_lifetime_tracking(
2734 &self,
2735 mut server_end: fidl::EventPair,
2736 mut buffers_remaining: u32,
2737 ) -> Result<(), fidl::Error> {
2738 self.client.send::<BufferCollectionAttachLifetimeTrackingRequest>(
2739 (server_end, buffers_remaining),
2740 0x170d0f1d89d50989,
2741 fidl::encoding::DynamicFlags::empty(),
2742 )
2743 }
2744}
2745
2746pub struct BufferCollectionEventStream {
2747 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
2748}
2749
2750impl std::marker::Unpin for BufferCollectionEventStream {}
2751
2752impl futures::stream::FusedStream for BufferCollectionEventStream {
2753 fn is_terminated(&self) -> bool {
2754 self.event_receiver.is_terminated()
2755 }
2756}
2757
2758impl futures::Stream for BufferCollectionEventStream {
2759 type Item = Result<BufferCollectionEvent, fidl::Error>;
2760
2761 fn poll_next(
2762 mut self: std::pin::Pin<&mut Self>,
2763 cx: &mut std::task::Context<'_>,
2764 ) -> std::task::Poll<Option<Self::Item>> {
2765 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
2766 &mut self.event_receiver,
2767 cx
2768 )?) {
2769 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionEvent::decode(buf))),
2770 None => std::task::Poll::Ready(None),
2771 }
2772 }
2773}
2774
2775#[derive(Debug)]
2776pub enum BufferCollectionEvent {}
2777
2778impl BufferCollectionEvent {
2779 /// Decodes a message buffer as a [`BufferCollectionEvent`].
2780 fn decode(
2781 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
2782 ) -> Result<BufferCollectionEvent, fidl::Error> {
2783 let (bytes, _handles) = buf.split_mut();
2784 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
2785 debug_assert_eq!(tx_header.tx_id, 0);
2786 match tx_header.ordinal {
2787 _ => Err(fidl::Error::UnknownOrdinal {
2788 ordinal: tx_header.ordinal,
2789 protocol_name:
2790 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
2791 }),
2792 }
2793 }
2794}
2795
2796/// A Stream of incoming requests for fuchsia.sysmem/BufferCollection.
2797pub struct BufferCollectionRequestStream {
2798 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2799 is_terminated: bool,
2800}
2801
2802impl std::marker::Unpin for BufferCollectionRequestStream {}
2803
2804impl futures::stream::FusedStream for BufferCollectionRequestStream {
2805 fn is_terminated(&self) -> bool {
2806 self.is_terminated
2807 }
2808}
2809
2810impl fidl::endpoints::RequestStream for BufferCollectionRequestStream {
2811 type Protocol = BufferCollectionMarker;
2812 type ControlHandle = BufferCollectionControlHandle;
2813
2814 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
2815 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
2816 }
2817
2818 fn control_handle(&self) -> Self::ControlHandle {
2819 BufferCollectionControlHandle { inner: self.inner.clone() }
2820 }
2821
2822 fn into_inner(
2823 self,
2824 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
2825 {
2826 (self.inner, self.is_terminated)
2827 }
2828
2829 fn from_inner(
2830 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2831 is_terminated: bool,
2832 ) -> Self {
2833 Self { inner, is_terminated }
2834 }
2835}
2836
2837impl futures::Stream for BufferCollectionRequestStream {
2838 type Item = Result<BufferCollectionRequest, fidl::Error>;
2839
2840 fn poll_next(
2841 mut self: std::pin::Pin<&mut Self>,
2842 cx: &mut std::task::Context<'_>,
2843 ) -> std::task::Poll<Option<Self::Item>> {
2844 let this = &mut *self;
2845 if this.inner.check_shutdown(cx) {
2846 this.is_terminated = true;
2847 return std::task::Poll::Ready(None);
2848 }
2849 if this.is_terminated {
2850 panic!("polled BufferCollectionRequestStream after completion");
2851 }
2852 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
2853 |bytes, handles| {
2854 match this.inner.channel().read_etc(cx, bytes, handles) {
2855 std::task::Poll::Ready(Ok(())) => {}
2856 std::task::Poll::Pending => return std::task::Poll::Pending,
2857 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
2858 this.is_terminated = true;
2859 return std::task::Poll::Ready(None);
2860 }
2861 std::task::Poll::Ready(Err(e)) => {
2862 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
2863 e.into(),
2864 ))));
2865 }
2866 }
2867
2868 // A message has been received from the channel
2869 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
2870
2871 std::task::Poll::Ready(Some(match header.ordinal {
2872 0x4577e238ae26291 => {
2873 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
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::Sync {
2882 responder: BufferCollectionSyncResponder {
2883 control_handle: std::mem::ManuallyDrop::new(control_handle),
2884 tx_id: header.tx_id,
2885 },
2886 })
2887 }
2888 0x5b1d7a4f5681fca7 => {
2889 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2890 let mut req = fidl::new_empty!(
2891 fidl::encoding::EmptyPayload,
2892 fidl::encoding::DefaultFuchsiaResourceDialect
2893 );
2894 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2895 let control_handle =
2896 BufferCollectionControlHandle { inner: this.inner.clone() };
2897 Ok(BufferCollectionRequest::Close { control_handle })
2898 }
2899 0x77a41bb6217e2443 => {
2900 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2901 let mut req = fidl::new_empty!(
2902 NodeSetNameRequest,
2903 fidl::encoding::DefaultFuchsiaResourceDialect
2904 );
2905 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
2906 let control_handle =
2907 BufferCollectionControlHandle { inner: this.inner.clone() };
2908 Ok(BufferCollectionRequest::SetName {
2909 priority: req.priority,
2910 name: req.name,
2911
2912 control_handle,
2913 })
2914 }
2915 0x7275759070eb5ee2 => {
2916 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2917 let mut req = fidl::new_empty!(
2918 NodeSetDebugClientInfoRequest,
2919 fidl::encoding::DefaultFuchsiaResourceDialect
2920 );
2921 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
2922 let control_handle =
2923 BufferCollectionControlHandle { inner: this.inner.clone() };
2924 Ok(BufferCollectionRequest::SetDebugClientInfo {
2925 name: req.name,
2926 id: req.id,
2927
2928 control_handle,
2929 })
2930 }
2931 0x46d38f4772638867 => {
2932 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2933 let mut req = fidl::new_empty!(
2934 NodeSetDebugTimeoutLogDeadlineRequest,
2935 fidl::encoding::DefaultFuchsiaResourceDialect
2936 );
2937 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
2938 let control_handle =
2939 BufferCollectionControlHandle { inner: this.inner.clone() };
2940 Ok(BufferCollectionRequest::SetDebugTimeoutLogDeadline {
2941 deadline: req.deadline,
2942
2943 control_handle,
2944 })
2945 }
2946 0x6bfbe2cf1701d288 => {
2947 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2948 let mut req = fidl::new_empty!(
2949 fidl::encoding::EmptyPayload,
2950 fidl::encoding::DefaultFuchsiaResourceDialect
2951 );
2952 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2953 let control_handle =
2954 BufferCollectionControlHandle { inner: this.inner.clone() };
2955 Ok(BufferCollectionRequest::SetVerboseLogging { control_handle })
2956 }
2957 0x467b7c75c35c3b84 => {
2958 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2959 let mut req = fidl::new_empty!(
2960 fidl::encoding::EmptyPayload,
2961 fidl::encoding::DefaultFuchsiaResourceDialect
2962 );
2963 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
2964 let control_handle =
2965 BufferCollectionControlHandle { inner: this.inner.clone() };
2966 Ok(BufferCollectionRequest::GetNodeRef {
2967 responder: BufferCollectionGetNodeRefResponder {
2968 control_handle: std::mem::ManuallyDrop::new(control_handle),
2969 tx_id: header.tx_id,
2970 },
2971 })
2972 }
2973 0x33a2a7aff2776c07 => {
2974 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2975 let mut req = fidl::new_empty!(
2976 NodeIsAlternateForRequest,
2977 fidl::encoding::DefaultFuchsiaResourceDialect
2978 );
2979 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
2980 let control_handle =
2981 BufferCollectionControlHandle { inner: this.inner.clone() };
2982 Ok(BufferCollectionRequest::IsAlternateFor {
2983 node_ref: req.node_ref,
2984
2985 responder: BufferCollectionIsAlternateForResponder {
2986 control_handle: std::mem::ManuallyDrop::new(control_handle),
2987 tx_id: header.tx_id,
2988 },
2989 })
2990 }
2991 0x4d9c3406c213227b => {
2992 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
2993 let mut req = fidl::new_empty!(
2994 BufferCollectionSetConstraintsRequest,
2995 fidl::encoding::DefaultFuchsiaResourceDialect
2996 );
2997 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionSetConstraintsRequest>(&header, _body_bytes, handles, &mut req)?;
2998 let control_handle =
2999 BufferCollectionControlHandle { inner: this.inner.clone() };
3000 Ok(BufferCollectionRequest::SetConstraints {
3001 has_constraints: req.has_constraints,
3002 constraints: req.constraints,
3003
3004 control_handle,
3005 })
3006 }
3007 0x714667ea2a29a3a2 => {
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::WaitForBuffersAllocated {
3017 responder: BufferCollectionWaitForBuffersAllocatedResponder {
3018 control_handle: std::mem::ManuallyDrop::new(control_handle),
3019 tx_id: header.tx_id,
3020 },
3021 })
3022 }
3023 0x245bb81f79189e9 => {
3024 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
3025 let mut req = fidl::new_empty!(
3026 fidl::encoding::EmptyPayload,
3027 fidl::encoding::DefaultFuchsiaResourceDialect
3028 );
3029 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
3030 let control_handle =
3031 BufferCollectionControlHandle { inner: this.inner.clone() };
3032 Ok(BufferCollectionRequest::CheckBuffersAllocated {
3033 responder: BufferCollectionCheckBuffersAllocatedResponder {
3034 control_handle: std::mem::ManuallyDrop::new(control_handle),
3035 tx_id: header.tx_id,
3036 },
3037 })
3038 }
3039 0x6f5adcca4ac7443e => {
3040 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
3041 let mut req = fidl::new_empty!(
3042 BufferCollectionAttachTokenRequest,
3043 fidl::encoding::DefaultFuchsiaResourceDialect
3044 );
3045 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachTokenRequest>(&header, _body_bytes, handles, &mut req)?;
3046 let control_handle =
3047 BufferCollectionControlHandle { inner: this.inner.clone() };
3048 Ok(BufferCollectionRequest::AttachToken {
3049 rights_attenuation_mask: req.rights_attenuation_mask,
3050 token_request: req.token_request,
3051
3052 control_handle,
3053 })
3054 }
3055 0x170d0f1d89d50989 => {
3056 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
3057 let mut req = fidl::new_empty!(
3058 BufferCollectionAttachLifetimeTrackingRequest,
3059 fidl::encoding::DefaultFuchsiaResourceDialect
3060 );
3061 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionAttachLifetimeTrackingRequest>(&header, _body_bytes, handles, &mut req)?;
3062 let control_handle =
3063 BufferCollectionControlHandle { inner: this.inner.clone() };
3064 Ok(BufferCollectionRequest::AttachLifetimeTracking {
3065 server_end: req.server_end,
3066 buffers_remaining: req.buffers_remaining,
3067
3068 control_handle,
3069 })
3070 }
3071 _ => Err(fidl::Error::UnknownOrdinal {
3072 ordinal: header.ordinal,
3073 protocol_name:
3074 <BufferCollectionMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
3075 }),
3076 }))
3077 },
3078 )
3079 }
3080}
3081
3082/// BufferCollection is a connection directly from a participant to sysmem re.
3083/// a logical BufferCollection; typically the logical BufferCollection is shared
3084/// with other participants. In other words, an instance of the BufferCollection
3085/// interface is a view of a "logical buffer collection".
3086///
3087/// This connection exists to facilitate async indication of when the logical
3088/// BufferCollection has been populated with buffers.
3089///
3090/// Also, the channel's closure by the server is an indication to the client
3091/// that the client should close all VMO handles that were obtained from the
3092/// BufferCollection ASAP.
3093///
3094/// Also, this interface may in future allow specifying constraints in other
3095/// ways, and may allow for back-and-forth negotiation of constraints to some
3096/// degree.
3097///
3098/// This interface may in future allow for more than 64 VMO handles per
3099/// BufferCollection, but currently the limit is 64.
3100///
3101/// This interface may in future allow for allocating/deallocating single
3102/// buffers.
3103///
3104/// Some initiators may wait a short duration until all old logical
3105/// BufferCollection VMO handles have closed (or until the short duration times
3106/// out) before allocating a new BufferCollection, to help control physical
3107/// memory fragmentation and avoid overlap of buffer allocation lifetimes for
3108/// the old and new collections. Collections can be large enough that it's worth
3109/// avoiding allocation overlap (in time).
3110#[derive(Debug)]
3111pub enum BufferCollectionRequest {
3112 /// Ensure that previous messages, including Duplicate() messages on a
3113 /// token, collection, or group, have been received server side.
3114 ///
3115 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
3116 /// valid sysmem token risks the Sync() hanging forever. See
3117 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
3118 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
3119 /// Another way is to pass the token to BindSharedCollection(), which also
3120 /// validates the token as part of exchanging it for a BufferCollection
3121 /// channel, and BufferCollection Sync() can then be used.
3122 ///
3123 /// After a Sync(), it's then safe to send the client end of token_request
3124 /// to another participant knowing the server will recognize the token when
3125 /// it's sent into BindSharedCollection() by the other participant.
3126 ///
3127 /// Other options include waiting for each token.Duplicate() to complete
3128 /// individually (using separate call to token.Sync() after each), or
3129 /// calling Sync() on BufferCollection after the token has been turned in
3130 /// via BindSharedCollection().
3131 ///
3132 /// Another way to mitigate is to avoid calling Sync() on the token, and
3133 /// instead later deal with potential failure of BufferCollection.Sync() if
3134 /// the original token was invalid. This option can be preferable from a
3135 /// performance point of view, but requires client code to delay sending
3136 /// tokens duplicated from this token until after client code has converted
3137 /// the duplicating token to a BufferCollection and received successful
3138 /// response from BufferCollection.Sync().
3139 ///
3140 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
3141 /// When BufferCollection.Sync() isn't feasible, the caller must already
3142 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
3143 /// hang forever. See ValidateBufferCollectionToken() to check token
3144 /// validity first if the token isn't already known to be (is/was) valid.
3145 Sync { responder: BufferCollectionSyncResponder },
3146 /// On a BufferCollectionToken channel:
3147 ///
3148 /// Normally a participant will convert a BufferCollectionToken into a
3149 /// BufferCollection view, but a participant is also free to Close() the
3150 /// token (and then close the channel immediately or shortly later in
3151 /// response to server closing its end), which avoids causing logical buffer
3152 /// collection failure. Â Normally an unexpected token channel close will
3153 /// cause logical buffer collection failure (the only exceptions being
3154 /// certain cases involving AttachToken() or SetDispensable()).
3155 ///
3156 /// On a BufferCollection channel:
3157 ///
3158 /// By default the server handles unexpected failure of a BufferCollection
3159 /// by failing the whole logical buffer collection. Partly this is to
3160 /// expedite closing VMO handles to reclaim memory when any participant
3161 /// fails. If a participant would like to cleanly close a BufferCollection
3162 /// view without causing logical buffer collection failure, the participant
3163 /// can send Close() before closing the client end of the BufferCollection
3164 /// channel. If this is the last BufferCollection view, the logical buffer
3165 /// collection will still go away. The Close() can occur before or after
3166 /// SetConstraints(). If before SetConstraints(), the buffer collection
3167 /// won't require constraints from this node in order to allocate. If
3168 /// after SetConstraints(), the constraints are retained and aggregated
3169 /// along with any subsequent logical allocation(s), despite the lack of
3170 /// channel connection.
3171 ///
3172 /// On a BufferCollectionTokenGroup channel:
3173 ///
3174 /// By default, unexpected failure of a BufferCollectionTokenGroup will
3175 /// trigger failure of the logical BufferCollectionTokenGroup and will
3176 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
3177 /// channel without failing the logical group or propagating failure, send
3178 /// Close() before closing the channel client endpoint.
3179 ///
3180 /// If Close() occurs before AllChildrenPresent(), the logical buffer
3181 /// collection will still fail despite the Close() (because sysmem can't be
3182 /// sure whether all relevant children were created, so it's ambiguous
3183 /// whether all relevant constraints will be provided to sysmem). If
3184 /// Close() occurs after AllChildrenPresent(), the children and all their
3185 /// constraints remain intact (just as they would if the
3186 /// BufferCollectionTokenGroup channel had remained open), and the close
3187 /// doesn't trigger or propagate failure.
3188 Close { control_handle: BufferCollectionControlHandle },
3189 /// Set a name for VMOs in this buffer collection. The name may be truncated
3190 /// shorter. The name only affects VMOs allocated after it's set - this call
3191 /// does not rename existing VMOs. If multiple clients set different names
3192 /// then the larger priority value will win.
3193 SetName { priority: u32, name: String, control_handle: BufferCollectionControlHandle },
3194 /// Set information about the current client that can be used by sysmem to
3195 /// help debug leaking memory and hangs waiting for constraints. |name| can
3196 /// be an arbitrary string, but the current process name (see
3197 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
3198 /// arbitrary id, but the current process ID (see
3199 /// fsl::GetCurrentProcessKoid()) is a good default.
3200 ///
3201 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
3202 /// indicate which client is closing their channel first, leading to
3203 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
3204 /// over, but if happening earlier than expected, the
3205 /// client-channel-specific name can help diagnose where the failure is
3206 /// first coming from, from sysmem's point of view).
3207 ///
3208 /// By default (unless overriden by this message or using
3209 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
3210 /// parent Node at the time the child Node is created. While this can be
3211 /// better than nothing, it's often better for each participant to use
3212 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
3213 /// info directly relevant to the current client. Also, SetVerboseLogging()
3214 /// can be used to help disambiguate if a Node is suspected of having info
3215 /// that was copied from its parent.
3216 SetDebugClientInfo { name: String, id: u64, control_handle: BufferCollectionControlHandle },
3217 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
3218 /// after creating a collection. Clients can call this method to change
3219 /// when the log is printed. If multiple client set the deadline, it's
3220 /// unspecified which deadline will take effect.
3221 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: BufferCollectionControlHandle },
3222 /// Verbose logging includes constraints set via SetConstraints() from each
3223 /// client along with info set via SetDebugClientInfo() and the structure of
3224 /// the tree of Node(s).
3225 ///
3226 /// Normally sysmem prints only a single line complaint when aggregation
3227 /// fails, with just the specific detailed reason that aggregation failed,
3228 /// with minimal context. While this is often enough to diagnose a problem
3229 /// if only a small change was made and the system had been working before
3230 /// the small change, it's often not particularly helpful for getting a new
3231 /// buffer collection to work for the first time. Especially with more
3232 /// complex trees of nodes, involving things like AttachToken(),
3233 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
3234 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
3235 /// looks like and why it's failing a logical allocation, or why a tree or
3236 /// sub-tree is failing sooner than expected.
3237 ///
3238 /// The intent of the extra logging is to be acceptable from a performance
3239 /// point of view, if only enabled on a low number of buffer collections.
3240 /// If we're not tracking down a bug, we shouldn't send this message.
3241 ///
3242 /// If too many participants leave verbose logging enabled, we may end up
3243 /// needing to require that system-wide sysmem verbose logging be permitted
3244 /// via some other setting, to avoid sysmem spamming the log too much due to
3245 /// this message.
3246 ///
3247 /// This may be a NOP for some nodes due to intentional policy associated
3248 /// with the node, if we don't trust a node enough to let it turn on verbose
3249 /// logging.
3250 SetVerboseLogging { control_handle: BufferCollectionControlHandle },
3251 /// This gets an event handle that can be used as a parameter to
3252 /// IsAlternateFor() called on any Node. The client will not be granted the
3253 /// right to signal this event, as this handle should only be used as proof
3254 /// that the client obtained this handle from this Node.
3255 ///
3256 /// Because this is a get not a set, no Sync() is needed between the
3257 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
3258 /// potentially being on different channels.
3259 ///
3260 /// See also IsAlternateFor().
3261 GetNodeRef { responder: BufferCollectionGetNodeRefResponder },
3262 /// This checks whether the calling node is in a subtree rooted at a
3263 /// different child token of a common parent BufferCollectionTokenGroup, in
3264 /// relation to the passed-in node_ref.
3265 ///
3266 /// This call is for assisting with admission control de-duplication, and
3267 /// with debugging.
3268 ///
3269 /// The node_ref must be obtained using GetNodeRef() of a
3270 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
3271 ///
3272 /// The node_ref can be a duplicated handle; it's not necessary to call
3273 /// GetNodeRef() for every call to IsAlternateFor().
3274 ///
3275 /// If a calling token may not actually be a valid token at all due to
3276 /// a potentially hostile/untrusted provider of the token, call
3277 /// ValidateBufferCollectionToken() first instead of potentially getting
3278 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
3279 /// token not being a real token (not really talking to sysmem). Another
3280 /// option is to call BindSharedCollection with this token first which also
3281 /// validates the token along with converting it to a BufferCollection, then
3282 /// call BufferCollection IsAlternateFor().
3283 ///
3284 /// error values:
3285 ///
3286 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
3287 /// buffer collection as the calling Node. Before logical allocation and
3288 /// within the same logical allocation sub-tree, this essentially means that
3289 /// the node_ref was never part of this logical buffer collection, since
3290 /// before logical allocation all node_refs that come into existence remain
3291 /// in existence at least until logical allocation (including Node(s) that
3292 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
3293 /// to be returned, this Node's channel needs to still be connected server
3294 /// side, which won't be the case if the whole logical allocation has
3295 /// failed. After logical allocation or in a different logical allocation
3296 /// sub-tree there are additional potential reasons for this error. For
3297 /// example a different logical allocation (separated from this Node(s)
3298 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
3299 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
3300 /// exist and may select a different child sub-tree than the sub-tree the
3301 /// node_ref is in causing deletion of the node_ref Node. The only time
3302 /// sysmem keeps a Node around after that Node has no corresponding channel
3303 /// is when Close() is used and the Node's sub-tree has not yet failed.
3304 /// Another reason for this error is if the node_ref is an eventpair handle
3305 /// with sufficient rights, but isn't actually a real node_ref obtained from
3306 /// GetNodeRef().
3307 ///
3308 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
3309 /// eventpair handle, or doesn't have the needed rights expected on a real
3310 /// node_ref.
3311 ///
3312 /// No other failing status codes are returned by this call. However,
3313 /// sysmem may add additional codes in future, so the client should have
3314 /// sensible default handling for any failing status code.
3315 ///
3316 /// On success, is_alternate has the following meaning:
3317 /// * true - The first parent node in common between the calling node and
3318 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
3319 /// the calling Node and the node_ref Node will _not_ have both their
3320 /// constraints apply - rather sysmem will choose one or the other of
3321 /// the constraints - never both. This is because only one child of
3322 /// a BufferCollectionTokenGroup is selected during logical allocation,
3323 /// with only that one child's sub-tree contributing to constraints
3324 /// aggregation.
3325 /// * false - The first parent node in common between the calling Node and
3326 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
3327 /// this means the first parent node in common is a
3328 /// BufferCollectionToken or BufferCollection (regardless of not
3329 /// Close()ed or Close()ed). This means that the calling Node and the
3330 /// node_ref Node _may_ have both their constraints apply during
3331 /// constraints aggregation of the logical allocation, if both Node(s)
3332 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
3333 /// In this case, there is no BufferCollectionTokenGroup that will
3334 /// directly prevent the two Node(s) from both being selected and their
3335 /// constraints both aggregated, but even when false, one or both
3336 /// Node(s) may still be eliminated from consideration if one or both
3337 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
3338 /// which selects a child sub-tree other than the sub-tree containing
3339 /// the calling Node or node_ref Node.
3340 IsAlternateFor { node_ref: fidl::Event, responder: BufferCollectionIsAlternateForResponder },
3341 /// Provide BufferCollectionConstraints to the logical BufferCollection.
3342 ///
3343 /// A participant may only call SetConstraints() once.
3344 ///
3345 /// Sometimes the initiator is a participant only in the sense of wanting to
3346 /// keep an eye on success/failure to populate with buffers, and zx.Status
3347 /// on failure. In that case, `has_constraints` can be false, and
3348 /// `constraints` will be ignored.
3349 ///
3350 /// VMO handles will not be provided to the client that sends null
3351 /// constraints - that can be intentional for an initiator that doesn't need
3352 /// VMO handles. Not having VMO handles doesn't prevent the initator from
3353 /// adjusting which portion of a buffer is considered valid and similar, but
3354 /// the initiator can't hold a VMO handle open to prevent the logical
3355 /// BufferCollection from cleaning up if the logical BufferCollection needs
3356 /// to go away regardless of the initiator's degree of involvement for
3357 /// whatever reason.
3358 ///
3359 /// For population of buffers to be attempted, all holders of a
3360 /// BufferCollection client channel need to call SetConstraints() before
3361 /// sysmem will attempt to allocate buffers.
3362 ///
3363 /// `has_constraints` if false, the constraints are effectively null, and
3364 /// `constraints` are ignored. The sender of null constraints won't get any
3365 /// VMO handles in BufferCollectionInfo, but can still find out how many
3366 /// buffers were allocated and can still refer to buffers by their
3367 /// buffer_index.
3368 ///
3369 /// `constraints` are constraints on the buffer collection.
3370 SetConstraints {
3371 has_constraints: bool,
3372 constraints: BufferCollectionConstraints,
3373 control_handle: BufferCollectionControlHandle,
3374 },
3375 /// This request completes when buffers have been allocated, responds with
3376 /// some failure detail if allocation has been attempted but failed.
3377 ///
3378 /// The following must occur before buffers will be allocated:
3379 /// * All BufferCollectionToken(s) of the logical BufferCollectionToken
3380 /// must be turned in via BindSharedCollection().
3381 /// * All BufferCollection(s) of the logical BufferCollection must have
3382 /// had SetConstraints() sent to them.
3383 ///
3384 /// Returns `ZX_OK` if successful.
3385 /// Returns `ZX_ERR_NO_MEMORY` if the request is valid but cannot be
3386 /// fulfilled due to resource exhaustion.
3387 /// Returns `ZX_ERR_ACCESS_DENIED` if the caller is not permitted to
3388 /// obtain the buffers it requested.
3389 /// Returns `ZX_ERR_INVALID_ARGS` if the request is malformed.
3390 /// Returns `ZX_ERR_NOT_SUPPORTED` if request is valid but cannot be
3391 /// satisfied, perhaps due to hardware limitations.
3392 ///
3393 /// `buffer_collection_info` has the VMO handles and other related info.
3394 WaitForBuffersAllocated { responder: BufferCollectionWaitForBuffersAllocatedResponder },
3395 /// This returns the same result code as WaitForBuffersAllocated if the
3396 /// buffer collection has been allocated or failed, or `ZX_ERR_UNAVAILABLE`
3397 /// if WaitForBuffersAllocated would block.
3398 CheckBuffersAllocated { responder: BufferCollectionCheckBuffersAllocatedResponder },
3399 /// Create a new token, for trying to add a new participant to an existing
3400 /// collection, if the existing collection's buffer counts, constraints,
3401 /// and participants allow.
3402 ///
3403 /// This can be useful in replacing a failed participant, and/or in
3404 /// adding/re-adding a participant after buffers have already been
3405 /// allocated.
3406 ///
3407 /// Failure of an attached token / collection does not propagate to the
3408 /// parent of the attached token. Failure does propagate from a normal
3409 /// child of a dispensable token to the dispensable token. Failure
3410 /// of a child is blocked from reaching its parent if the child is attached,
3411 /// or if the child is dispensable and the failure occurred after logical
3412 /// allocation.
3413 ///
3414 /// An initiator may in some scenarios choose to initially use a dispensable
3415 /// token for a given instance of a participant, and then later if the first
3416 /// instance of that participant fails, a new second instance of that
3417 /// participant my be given a token created with AttachToken().
3418 ///
3419 /// From the point of view of the client end of the BufferCollectionToken
3420 /// channel, the token acts like any other token. The client can
3421 /// Duplicate() the token as needed, and can send the token to a different
3422 /// process. The token should be converted to a BufferCollection channel
3423 /// as normal by calling BindSharedCollection(). SetConstraints() should
3424 /// be called on that BufferCollection channel.
3425 ///
3426 /// A success result from WaitForBuffersAllocated() means the new
3427 /// participant's constraints were satisfiable using the already-existing
3428 /// buffer collection, the already-established BufferCollectionInfo
3429 /// including image format constraints, and the already-existing other
3430 /// participants and their buffer counts. A failure result means the new
3431 /// participant's constraints cannot be satisfied using the existing
3432 /// buffer collection and its already-logically-allocated participants.
3433 /// Creating a new collection instead may allow all participant's
3434 /// constraints to be satisfied, assuming SetDispensable() is used in place
3435 /// of AttachToken(), or a normal token is used.
3436 ///
3437 /// A token created with AttachToken() performs constraints aggregation with
3438 /// all constraints currently in effect on the buffer collection, plus the
3439 /// attached token under consideration plus child tokens under the attached
3440 /// token which are not themselves an attached token or under such a token.
3441 ///
3442 /// Allocation of buffer_count to min_buffer_count_for_camping etc is
3443 /// first-come first-served, but a child can't logically allocate before
3444 /// all its parents have sent SetConstraints().
3445 ///
3446 /// See also SetDispensable(), which in contrast to AttachToken(), has the
3447 /// created token + children participate in constraints aggregation along
3448 /// with its parent.
3449 ///
3450 /// The newly created token needs to be Sync()ed to sysmem before the new
3451 /// token can be passed to BindSharedCollection(). The Sync() of the new
3452 /// token can be accomplished with BufferCollection.Sync() on this
3453 /// BufferCollection. Alternately BufferCollectionToken.Sync() on the new
3454 /// token also works. A BufferCollectionToken.Sync() can be started after
3455 /// any BufferCollectionToken.Duplicate() messages have been sent via the
3456 /// newly created token, to also sync those additional tokens to sysmem
3457 /// using a single round-trip.
3458 ///
3459 /// These values for rights_attenuation_mask result in no attenuation (note
3460 /// that 0 is not on this list; 0 will output an ERROR to the system log
3461 /// to help diagnose the bug in client code):
3462 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
3463 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
3464 AttachToken {
3465 rights_attenuation_mask: u32,
3466 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
3467 control_handle: BufferCollectionControlHandle,
3468 },
3469 /// AttachLifetimeTracking:
3470 ///
3471 /// AttachLifetimeTracking() is intended to allow a client to wait until an
3472 /// old logical buffer collection is fully or mostly deallocated before
3473 /// attempting allocation of a new logical buffer collection.
3474 ///
3475 /// Attach an eventpair endpoint to the logical buffer collection, so that
3476 /// the server_end will be closed when the number of buffers allocated
3477 /// drops to 'buffers_remaining'. The server_end won't close until after
3478 /// logical allocation has completed.
3479 ///
3480 /// If logical allocation fails, such as for an attached sub-tree (using
3481 /// AttachToken()), the server_end will close during that failure regardless
3482 /// of the number of buffers potenitally allocated in the overall logical
3483 /// buffer collection.
3484 ///
3485 /// The lifetime signalled by this event includes asynchronous cleanup of
3486 /// allocated buffers, and this asynchronous cleanup cannot occur until all
3487 /// holders of VMO handles to the buffers have closed those VMO handles.
3488 /// Therefore clients should take care not to become blocked forever waiting
3489 /// for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the
3490 /// participants using the logical buffer collection are less trusted or
3491 /// less reliable.
3492 ///
3493 /// The buffers_remaining parameter allows waiting for all but
3494 /// buffers_remaining buffers to be fully deallocated. This can be useful
3495 /// in situations where a known number of buffers are intentionally not
3496 /// closed so that the data can continue to be used, such as for keeping the
3497 /// last available video picture displayed in the UI even if the video
3498 /// stream was using protected output buffers. It's outside the scope of
3499 /// the BufferCollection interface (at least for now) to determine how many
3500 /// buffers may be held without closing, but it'll typically be in the range
3501 /// 0-2.
3502 ///
3503 /// This mechanism is meant to be compatible with other protocols providing
3504 /// a similar AttachLifetimeTracking() mechanism, in that duplicates of the
3505 /// same event can be sent to more than one AttachLifetimeTracking(), and
3506 /// the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime
3507 /// over conditions are met (all holders of duplicates have closed their
3508 /// handle(s)).
3509 ///
3510 /// There is no way to cancel an attach. Closing the client end of the
3511 /// eventpair doesn't subtract from the number of pending attach(es).
3512 ///
3513 /// Closing the client's end doesn't result in any action by the server.
3514 /// If the server listens to events from the client end at all, it is for
3515 /// debug logging only.
3516 ///
3517 /// The server intentionally doesn't "trust" any bits signalled by the
3518 /// client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED
3519 /// which can't be triggered early, and is only triggered when all handles
3520 /// to server_end are closed. No meaning is associated with any of the
3521 /// other signal bits, and clients should functionally ignore any other
3522 /// signal bits on either end of the eventpair or its peer.
3523 ///
3524 /// The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but
3525 /// must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to
3526 /// transfer without causing CodecFactory channel failure).
3527 AttachLifetimeTracking {
3528 server_end: fidl::EventPair,
3529 buffers_remaining: u32,
3530 control_handle: BufferCollectionControlHandle,
3531 },
3532}
3533
3534impl BufferCollectionRequest {
3535 #[allow(irrefutable_let_patterns)]
3536 pub fn into_sync(self) -> Option<(BufferCollectionSyncResponder)> {
3537 if let BufferCollectionRequest::Sync { responder } = self {
3538 Some((responder))
3539 } else {
3540 None
3541 }
3542 }
3543
3544 #[allow(irrefutable_let_patterns)]
3545 pub fn into_close(self) -> Option<(BufferCollectionControlHandle)> {
3546 if let BufferCollectionRequest::Close { control_handle } = self {
3547 Some((control_handle))
3548 } else {
3549 None
3550 }
3551 }
3552
3553 #[allow(irrefutable_let_patterns)]
3554 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionControlHandle)> {
3555 if let BufferCollectionRequest::SetName { priority, name, control_handle } = self {
3556 Some((priority, name, control_handle))
3557 } else {
3558 None
3559 }
3560 }
3561
3562 #[allow(irrefutable_let_patterns)]
3563 pub fn into_set_debug_client_info(
3564 self,
3565 ) -> Option<(String, u64, BufferCollectionControlHandle)> {
3566 if let BufferCollectionRequest::SetDebugClientInfo { name, id, control_handle } = self {
3567 Some((name, id, control_handle))
3568 } else {
3569 None
3570 }
3571 }
3572
3573 #[allow(irrefutable_let_patterns)]
3574 pub fn into_set_debug_timeout_log_deadline(
3575 self,
3576 ) -> Option<(i64, BufferCollectionControlHandle)> {
3577 if let BufferCollectionRequest::SetDebugTimeoutLogDeadline { deadline, control_handle } =
3578 self
3579 {
3580 Some((deadline, control_handle))
3581 } else {
3582 None
3583 }
3584 }
3585
3586 #[allow(irrefutable_let_patterns)]
3587 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionControlHandle)> {
3588 if let BufferCollectionRequest::SetVerboseLogging { control_handle } = self {
3589 Some((control_handle))
3590 } else {
3591 None
3592 }
3593 }
3594
3595 #[allow(irrefutable_let_patterns)]
3596 pub fn into_get_node_ref(self) -> Option<(BufferCollectionGetNodeRefResponder)> {
3597 if let BufferCollectionRequest::GetNodeRef { responder } = self {
3598 Some((responder))
3599 } else {
3600 None
3601 }
3602 }
3603
3604 #[allow(irrefutable_let_patterns)]
3605 pub fn into_is_alternate_for(
3606 self,
3607 ) -> Option<(fidl::Event, BufferCollectionIsAlternateForResponder)> {
3608 if let BufferCollectionRequest::IsAlternateFor { node_ref, responder } = self {
3609 Some((node_ref, responder))
3610 } else {
3611 None
3612 }
3613 }
3614
3615 #[allow(irrefutable_let_patterns)]
3616 pub fn into_set_constraints(
3617 self,
3618 ) -> Option<(bool, BufferCollectionConstraints, BufferCollectionControlHandle)> {
3619 if let BufferCollectionRequest::SetConstraints {
3620 has_constraints,
3621 constraints,
3622 control_handle,
3623 } = self
3624 {
3625 Some((has_constraints, constraints, control_handle))
3626 } else {
3627 None
3628 }
3629 }
3630
3631 #[allow(irrefutable_let_patterns)]
3632 pub fn into_wait_for_buffers_allocated(
3633 self,
3634 ) -> Option<(BufferCollectionWaitForBuffersAllocatedResponder)> {
3635 if let BufferCollectionRequest::WaitForBuffersAllocated { responder } = self {
3636 Some((responder))
3637 } else {
3638 None
3639 }
3640 }
3641
3642 #[allow(irrefutable_let_patterns)]
3643 pub fn into_check_buffers_allocated(
3644 self,
3645 ) -> Option<(BufferCollectionCheckBuffersAllocatedResponder)> {
3646 if let BufferCollectionRequest::CheckBuffersAllocated { responder } = self {
3647 Some((responder))
3648 } else {
3649 None
3650 }
3651 }
3652
3653 #[allow(irrefutable_let_patterns)]
3654 pub fn into_attach_token(
3655 self,
3656 ) -> Option<(
3657 u32,
3658 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
3659 BufferCollectionControlHandle,
3660 )> {
3661 if let BufferCollectionRequest::AttachToken {
3662 rights_attenuation_mask,
3663 token_request,
3664 control_handle,
3665 } = self
3666 {
3667 Some((rights_attenuation_mask, token_request, control_handle))
3668 } else {
3669 None
3670 }
3671 }
3672
3673 #[allow(irrefutable_let_patterns)]
3674 pub fn into_attach_lifetime_tracking(
3675 self,
3676 ) -> Option<(fidl::EventPair, u32, BufferCollectionControlHandle)> {
3677 if let BufferCollectionRequest::AttachLifetimeTracking {
3678 server_end,
3679 buffers_remaining,
3680 control_handle,
3681 } = self
3682 {
3683 Some((server_end, buffers_remaining, control_handle))
3684 } else {
3685 None
3686 }
3687 }
3688
3689 /// Name of the method defined in FIDL
3690 pub fn method_name(&self) -> &'static str {
3691 match *self {
3692 BufferCollectionRequest::Sync { .. } => "sync",
3693 BufferCollectionRequest::Close { .. } => "close",
3694 BufferCollectionRequest::SetName { .. } => "set_name",
3695 BufferCollectionRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
3696 BufferCollectionRequest::SetDebugTimeoutLogDeadline { .. } => {
3697 "set_debug_timeout_log_deadline"
3698 }
3699 BufferCollectionRequest::SetVerboseLogging { .. } => "set_verbose_logging",
3700 BufferCollectionRequest::GetNodeRef { .. } => "get_node_ref",
3701 BufferCollectionRequest::IsAlternateFor { .. } => "is_alternate_for",
3702 BufferCollectionRequest::SetConstraints { .. } => "set_constraints",
3703 BufferCollectionRequest::WaitForBuffersAllocated { .. } => "wait_for_buffers_allocated",
3704 BufferCollectionRequest::CheckBuffersAllocated { .. } => "check_buffers_allocated",
3705 BufferCollectionRequest::AttachToken { .. } => "attach_token",
3706 BufferCollectionRequest::AttachLifetimeTracking { .. } => "attach_lifetime_tracking",
3707 }
3708 }
3709}
3710
3711#[derive(Debug, Clone)]
3712pub struct BufferCollectionControlHandle {
3713 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
3714}
3715
3716impl BufferCollectionControlHandle {
3717 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
3718 self.inner.shutdown_with_epitaph(status.into())
3719 }
3720}
3721
3722impl fidl::endpoints::ControlHandle for BufferCollectionControlHandle {
3723 fn shutdown(&self) {
3724 self.inner.shutdown()
3725 }
3726
3727 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
3728 self.inner.shutdown_with_epitaph(status)
3729 }
3730
3731 fn is_closed(&self) -> bool {
3732 self.inner.channel().is_closed()
3733 }
3734 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
3735 self.inner.channel().on_closed()
3736 }
3737
3738 #[cfg(target_os = "fuchsia")]
3739 fn signal_peer(
3740 &self,
3741 clear_mask: zx::Signals,
3742 set_mask: zx::Signals,
3743 ) -> Result<(), zx_status::Status> {
3744 use fidl::Peered;
3745 self.inner.channel().signal_peer(clear_mask, set_mask)
3746 }
3747}
3748
3749impl BufferCollectionControlHandle {}
3750
3751#[must_use = "FIDL methods require a response to be sent"]
3752#[derive(Debug)]
3753pub struct BufferCollectionSyncResponder {
3754 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3755 tx_id: u32,
3756}
3757
3758/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3759/// if the responder is dropped without sending a response, so that the client
3760/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3761impl std::ops::Drop for BufferCollectionSyncResponder {
3762 fn drop(&mut self) {
3763 self.control_handle.shutdown();
3764 // Safety: drops once, never accessed again
3765 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3766 }
3767}
3768
3769impl fidl::endpoints::Responder for BufferCollectionSyncResponder {
3770 type ControlHandle = BufferCollectionControlHandle;
3771
3772 fn control_handle(&self) -> &BufferCollectionControlHandle {
3773 &self.control_handle
3774 }
3775
3776 fn drop_without_shutdown(mut self) {
3777 // Safety: drops once, never accessed again due to mem::forget
3778 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3779 // Prevent Drop from running (which would shut down the channel)
3780 std::mem::forget(self);
3781 }
3782}
3783
3784impl BufferCollectionSyncResponder {
3785 /// Sends a response to the FIDL transaction.
3786 ///
3787 /// Sets the channel to shutdown if an error occurs.
3788 pub fn send(self) -> Result<(), fidl::Error> {
3789 let _result = self.send_raw();
3790 if _result.is_err() {
3791 self.control_handle.shutdown();
3792 }
3793 self.drop_without_shutdown();
3794 _result
3795 }
3796
3797 /// Similar to "send" but does not shutdown the channel if an error occurs.
3798 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
3799 let _result = self.send_raw();
3800 self.drop_without_shutdown();
3801 _result
3802 }
3803
3804 fn send_raw(&self) -> Result<(), fidl::Error> {
3805 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
3806 (),
3807 self.tx_id,
3808 0x4577e238ae26291,
3809 fidl::encoding::DynamicFlags::empty(),
3810 )
3811 }
3812}
3813
3814#[must_use = "FIDL methods require a response to be sent"]
3815#[derive(Debug)]
3816pub struct BufferCollectionGetNodeRefResponder {
3817 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3818 tx_id: u32,
3819}
3820
3821/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3822/// if the responder is dropped without sending a response, so that the client
3823/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3824impl std::ops::Drop for BufferCollectionGetNodeRefResponder {
3825 fn drop(&mut self) {
3826 self.control_handle.shutdown();
3827 // Safety: drops once, never accessed again
3828 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3829 }
3830}
3831
3832impl fidl::endpoints::Responder for BufferCollectionGetNodeRefResponder {
3833 type ControlHandle = BufferCollectionControlHandle;
3834
3835 fn control_handle(&self) -> &BufferCollectionControlHandle {
3836 &self.control_handle
3837 }
3838
3839 fn drop_without_shutdown(mut self) {
3840 // Safety: drops once, never accessed again due to mem::forget
3841 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3842 // Prevent Drop from running (which would shut down the channel)
3843 std::mem::forget(self);
3844 }
3845}
3846
3847impl BufferCollectionGetNodeRefResponder {
3848 /// Sends a response to the FIDL transaction.
3849 ///
3850 /// Sets the channel to shutdown if an error occurs.
3851 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3852 let _result = self.send_raw(node_ref);
3853 if _result.is_err() {
3854 self.control_handle.shutdown();
3855 }
3856 self.drop_without_shutdown();
3857 _result
3858 }
3859
3860 /// Similar to "send" but does not shutdown the channel if an error occurs.
3861 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3862 let _result = self.send_raw(node_ref);
3863 self.drop_without_shutdown();
3864 _result
3865 }
3866
3867 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
3868 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
3869 (node_ref,),
3870 self.tx_id,
3871 0x467b7c75c35c3b84,
3872 fidl::encoding::DynamicFlags::empty(),
3873 )
3874 }
3875}
3876
3877#[must_use = "FIDL methods require a response to be sent"]
3878#[derive(Debug)]
3879pub struct BufferCollectionIsAlternateForResponder {
3880 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3881 tx_id: u32,
3882}
3883
3884/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3885/// if the responder is dropped without sending a response, so that the client
3886/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3887impl std::ops::Drop for BufferCollectionIsAlternateForResponder {
3888 fn drop(&mut self) {
3889 self.control_handle.shutdown();
3890 // Safety: drops once, never accessed again
3891 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3892 }
3893}
3894
3895impl fidl::endpoints::Responder for BufferCollectionIsAlternateForResponder {
3896 type ControlHandle = BufferCollectionControlHandle;
3897
3898 fn control_handle(&self) -> &BufferCollectionControlHandle {
3899 &self.control_handle
3900 }
3901
3902 fn drop_without_shutdown(mut self) {
3903 // Safety: drops once, never accessed again due to mem::forget
3904 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3905 // Prevent Drop from running (which would shut down the channel)
3906 std::mem::forget(self);
3907 }
3908}
3909
3910impl BufferCollectionIsAlternateForResponder {
3911 /// Sends a response to the FIDL transaction.
3912 ///
3913 /// Sets the channel to shutdown if an error occurs.
3914 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
3915 let _result = self.send_raw(result);
3916 if _result.is_err() {
3917 self.control_handle.shutdown();
3918 }
3919 self.drop_without_shutdown();
3920 _result
3921 }
3922
3923 /// Similar to "send" but does not shutdown the channel if an error occurs.
3924 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
3925 let _result = self.send_raw(result);
3926 self.drop_without_shutdown();
3927 _result
3928 }
3929
3930 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
3931 self.control_handle
3932 .inner
3933 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
3934 result.map(|is_alternate| (is_alternate,)),
3935 self.tx_id,
3936 0x33a2a7aff2776c07,
3937 fidl::encoding::DynamicFlags::empty(),
3938 )
3939 }
3940}
3941
3942#[must_use = "FIDL methods require a response to be sent"]
3943#[derive(Debug)]
3944pub struct BufferCollectionWaitForBuffersAllocatedResponder {
3945 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
3946 tx_id: u32,
3947}
3948
3949/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
3950/// if the responder is dropped without sending a response, so that the client
3951/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
3952impl std::ops::Drop for BufferCollectionWaitForBuffersAllocatedResponder {
3953 fn drop(&mut self) {
3954 self.control_handle.shutdown();
3955 // Safety: drops once, never accessed again
3956 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3957 }
3958}
3959
3960impl fidl::endpoints::Responder for BufferCollectionWaitForBuffersAllocatedResponder {
3961 type ControlHandle = BufferCollectionControlHandle;
3962
3963 fn control_handle(&self) -> &BufferCollectionControlHandle {
3964 &self.control_handle
3965 }
3966
3967 fn drop_without_shutdown(mut self) {
3968 // Safety: drops once, never accessed again due to mem::forget
3969 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
3970 // Prevent Drop from running (which would shut down the channel)
3971 std::mem::forget(self);
3972 }
3973}
3974
3975impl BufferCollectionWaitForBuffersAllocatedResponder {
3976 /// Sends a response to the FIDL transaction.
3977 ///
3978 /// Sets the channel to shutdown if an error occurs.
3979 pub fn send(
3980 self,
3981 mut status: i32,
3982 mut buffer_collection_info: BufferCollectionInfo2,
3983 ) -> Result<(), fidl::Error> {
3984 let _result = self.send_raw(status, buffer_collection_info);
3985 if _result.is_err() {
3986 self.control_handle.shutdown();
3987 }
3988 self.drop_without_shutdown();
3989 _result
3990 }
3991
3992 /// Similar to "send" but does not shutdown the channel if an error occurs.
3993 pub fn send_no_shutdown_on_err(
3994 self,
3995 mut status: i32,
3996 mut buffer_collection_info: BufferCollectionInfo2,
3997 ) -> Result<(), fidl::Error> {
3998 let _result = self.send_raw(status, buffer_collection_info);
3999 self.drop_without_shutdown();
4000 _result
4001 }
4002
4003 fn send_raw(
4004 &self,
4005 mut status: i32,
4006 mut buffer_collection_info: BufferCollectionInfo2,
4007 ) -> Result<(), fidl::Error> {
4008 self.control_handle.inner.send::<BufferCollectionWaitForBuffersAllocatedResponse>(
4009 (status, &mut buffer_collection_info),
4010 self.tx_id,
4011 0x714667ea2a29a3a2,
4012 fidl::encoding::DynamicFlags::empty(),
4013 )
4014 }
4015}
4016
4017#[must_use = "FIDL methods require a response to be sent"]
4018#[derive(Debug)]
4019pub struct BufferCollectionCheckBuffersAllocatedResponder {
4020 control_handle: std::mem::ManuallyDrop<BufferCollectionControlHandle>,
4021 tx_id: u32,
4022}
4023
4024/// Set the the channel to be shutdown (see [`BufferCollectionControlHandle::shutdown`])
4025/// if the responder is dropped without sending a response, so that the client
4026/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
4027impl std::ops::Drop for BufferCollectionCheckBuffersAllocatedResponder {
4028 fn drop(&mut self) {
4029 self.control_handle.shutdown();
4030 // Safety: drops once, never accessed again
4031 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4032 }
4033}
4034
4035impl fidl::endpoints::Responder for BufferCollectionCheckBuffersAllocatedResponder {
4036 type ControlHandle = BufferCollectionControlHandle;
4037
4038 fn control_handle(&self) -> &BufferCollectionControlHandle {
4039 &self.control_handle
4040 }
4041
4042 fn drop_without_shutdown(mut self) {
4043 // Safety: drops once, never accessed again due to mem::forget
4044 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
4045 // Prevent Drop from running (which would shut down the channel)
4046 std::mem::forget(self);
4047 }
4048}
4049
4050impl BufferCollectionCheckBuffersAllocatedResponder {
4051 /// Sends a response to the FIDL transaction.
4052 ///
4053 /// Sets the channel to shutdown if an error occurs.
4054 pub fn send(self, mut status: i32) -> Result<(), fidl::Error> {
4055 let _result = self.send_raw(status);
4056 if _result.is_err() {
4057 self.control_handle.shutdown();
4058 }
4059 self.drop_without_shutdown();
4060 _result
4061 }
4062
4063 /// Similar to "send" but does not shutdown the channel if an error occurs.
4064 pub fn send_no_shutdown_on_err(self, mut status: i32) -> Result<(), fidl::Error> {
4065 let _result = self.send_raw(status);
4066 self.drop_without_shutdown();
4067 _result
4068 }
4069
4070 fn send_raw(&self, mut status: i32) -> Result<(), fidl::Error> {
4071 self.control_handle.inner.send::<BufferCollectionCheckBuffersAllocatedResponse>(
4072 (status,),
4073 self.tx_id,
4074 0x245bb81f79189e9,
4075 fidl::encoding::DynamicFlags::empty(),
4076 )
4077 }
4078}
4079
4080#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
4081pub struct BufferCollectionTokenMarker;
4082
4083impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenMarker {
4084 type Proxy = BufferCollectionTokenProxy;
4085 type RequestStream = BufferCollectionTokenRequestStream;
4086 #[cfg(target_os = "fuchsia")]
4087 type SynchronousProxy = BufferCollectionTokenSynchronousProxy;
4088
4089 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionToken";
4090}
4091
4092pub trait BufferCollectionTokenProxyInterface: Send + Sync {
4093 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
4094 fn r#sync(&self) -> Self::SyncResponseFut;
4095 fn r#close(&self) -> Result<(), fidl::Error>;
4096 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
4097 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
4098 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
4099 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
4100 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
4101 + Send;
4102 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
4103 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
4104 + Send;
4105 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
4106 type DuplicateSyncResponseFut: std::future::Future<
4107 Output = Result<
4108 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
4109 fidl::Error,
4110 >,
4111 > + Send;
4112 fn r#duplicate_sync(
4113 &self,
4114 rights_attenuation_masks: &[fidl::Rights],
4115 ) -> Self::DuplicateSyncResponseFut;
4116 fn r#duplicate(
4117 &self,
4118 rights_attenuation_mask: u32,
4119 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
4120 ) -> Result<(), fidl::Error>;
4121 fn r#set_dispensable(&self) -> Result<(), fidl::Error>;
4122 fn r#create_buffer_collection_token_group(
4123 &self,
4124 group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
4125 ) -> Result<(), fidl::Error>;
4126}
4127#[derive(Debug)]
4128#[cfg(target_os = "fuchsia")]
4129pub struct BufferCollectionTokenSynchronousProxy {
4130 client: fidl::client::sync::Client,
4131}
4132
4133#[cfg(target_os = "fuchsia")]
4134impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenSynchronousProxy {
4135 type Proxy = BufferCollectionTokenProxy;
4136 type Protocol = BufferCollectionTokenMarker;
4137
4138 fn from_channel(inner: fidl::Channel) -> Self {
4139 Self::new(inner)
4140 }
4141
4142 fn into_channel(self) -> fidl::Channel {
4143 self.client.into_channel()
4144 }
4145
4146 fn as_channel(&self) -> &fidl::Channel {
4147 self.client.as_channel()
4148 }
4149}
4150
4151#[cfg(target_os = "fuchsia")]
4152impl BufferCollectionTokenSynchronousProxy {
4153 pub fn new(channel: fidl::Channel) -> Self {
4154 Self { client: fidl::client::sync::Client::new(channel) }
4155 }
4156
4157 pub fn into_channel(self) -> fidl::Channel {
4158 self.client.into_channel()
4159 }
4160
4161 /// Waits until an event arrives and returns it. It is safe for other
4162 /// threads to make concurrent requests while waiting for an event.
4163 pub fn wait_for_event(
4164 &self,
4165 deadline: zx::MonotonicInstant,
4166 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
4167 BufferCollectionTokenEvent::decode(
4168 self.client.wait_for_event::<BufferCollectionTokenMarker>(deadline)?,
4169 )
4170 }
4171
4172 /// Ensure that previous messages, including Duplicate() messages on a
4173 /// token, collection, or group, have been received server side.
4174 ///
4175 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
4176 /// valid sysmem token risks the Sync() hanging forever. See
4177 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
4178 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
4179 /// Another way is to pass the token to BindSharedCollection(), which also
4180 /// validates the token as part of exchanging it for a BufferCollection
4181 /// channel, and BufferCollection Sync() can then be used.
4182 ///
4183 /// After a Sync(), it's then safe to send the client end of token_request
4184 /// to another participant knowing the server will recognize the token when
4185 /// it's sent into BindSharedCollection() by the other participant.
4186 ///
4187 /// Other options include waiting for each token.Duplicate() to complete
4188 /// individually (using separate call to token.Sync() after each), or
4189 /// calling Sync() on BufferCollection after the token has been turned in
4190 /// via BindSharedCollection().
4191 ///
4192 /// Another way to mitigate is to avoid calling Sync() on the token, and
4193 /// instead later deal with potential failure of BufferCollection.Sync() if
4194 /// the original token was invalid. This option can be preferable from a
4195 /// performance point of view, but requires client code to delay sending
4196 /// tokens duplicated from this token until after client code has converted
4197 /// the duplicating token to a BufferCollection and received successful
4198 /// response from BufferCollection.Sync().
4199 ///
4200 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
4201 /// When BufferCollection.Sync() isn't feasible, the caller must already
4202 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
4203 /// hang forever. See ValidateBufferCollectionToken() to check token
4204 /// validity first if the token isn't already known to be (is/was) valid.
4205 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
4206 let _response = self.client.send_query::<
4207 fidl::encoding::EmptyPayload,
4208 fidl::encoding::EmptyPayload,
4209 BufferCollectionTokenMarker,
4210 >(
4211 (),
4212 0x4577e238ae26291,
4213 fidl::encoding::DynamicFlags::empty(),
4214 ___deadline,
4215 )?;
4216 Ok(_response)
4217 }
4218
4219 /// On a BufferCollectionToken channel:
4220 ///
4221 /// Normally a participant will convert a BufferCollectionToken into a
4222 /// BufferCollection view, but a participant is also free to Close() the
4223 /// token (and then close the channel immediately or shortly later in
4224 /// response to server closing its end), which avoids causing logical buffer
4225 /// collection failure. Â Normally an unexpected token channel close will
4226 /// cause logical buffer collection failure (the only exceptions being
4227 /// certain cases involving AttachToken() or SetDispensable()).
4228 ///
4229 /// On a BufferCollection channel:
4230 ///
4231 /// By default the server handles unexpected failure of a BufferCollection
4232 /// by failing the whole logical buffer collection. Partly this is to
4233 /// expedite closing VMO handles to reclaim memory when any participant
4234 /// fails. If a participant would like to cleanly close a BufferCollection
4235 /// view without causing logical buffer collection failure, the participant
4236 /// can send Close() before closing the client end of the BufferCollection
4237 /// channel. If this is the last BufferCollection view, the logical buffer
4238 /// collection will still go away. The Close() can occur before or after
4239 /// SetConstraints(). If before SetConstraints(), the buffer collection
4240 /// won't require constraints from this node in order to allocate. If
4241 /// after SetConstraints(), the constraints are retained and aggregated
4242 /// along with any subsequent logical allocation(s), despite the lack of
4243 /// channel connection.
4244 ///
4245 /// On a BufferCollectionTokenGroup channel:
4246 ///
4247 /// By default, unexpected failure of a BufferCollectionTokenGroup will
4248 /// trigger failure of the logical BufferCollectionTokenGroup and will
4249 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
4250 /// channel without failing the logical group or propagating failure, send
4251 /// Close() before closing the channel client endpoint.
4252 ///
4253 /// If Close() occurs before AllChildrenPresent(), the logical buffer
4254 /// collection will still fail despite the Close() (because sysmem can't be
4255 /// sure whether all relevant children were created, so it's ambiguous
4256 /// whether all relevant constraints will be provided to sysmem). If
4257 /// Close() occurs after AllChildrenPresent(), the children and all their
4258 /// constraints remain intact (just as they would if the
4259 /// BufferCollectionTokenGroup channel had remained open), and the close
4260 /// doesn't trigger or propagate failure.
4261 pub fn r#close(&self) -> Result<(), fidl::Error> {
4262 self.client.send::<fidl::encoding::EmptyPayload>(
4263 (),
4264 0x5b1d7a4f5681fca7,
4265 fidl::encoding::DynamicFlags::empty(),
4266 )
4267 }
4268
4269 /// Set a name for VMOs in this buffer collection. The name may be truncated
4270 /// shorter. The name only affects VMOs allocated after it's set - this call
4271 /// does not rename existing VMOs. If multiple clients set different names
4272 /// then the larger priority value will win.
4273 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
4274 self.client.send::<NodeSetNameRequest>(
4275 (priority, name),
4276 0x77a41bb6217e2443,
4277 fidl::encoding::DynamicFlags::empty(),
4278 )
4279 }
4280
4281 /// Set information about the current client that can be used by sysmem to
4282 /// help debug leaking memory and hangs waiting for constraints. |name| can
4283 /// be an arbitrary string, but the current process name (see
4284 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
4285 /// arbitrary id, but the current process ID (see
4286 /// fsl::GetCurrentProcessKoid()) is a good default.
4287 ///
4288 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
4289 /// indicate which client is closing their channel first, leading to
4290 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
4291 /// over, but if happening earlier than expected, the
4292 /// client-channel-specific name can help diagnose where the failure is
4293 /// first coming from, from sysmem's point of view).
4294 ///
4295 /// By default (unless overriden by this message or using
4296 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
4297 /// parent Node at the time the child Node is created. While this can be
4298 /// better than nothing, it's often better for each participant to use
4299 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
4300 /// info directly relevant to the current client. Also, SetVerboseLogging()
4301 /// can be used to help disambiguate if a Node is suspected of having info
4302 /// that was copied from its parent.
4303 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
4304 self.client.send::<NodeSetDebugClientInfoRequest>(
4305 (name, id),
4306 0x7275759070eb5ee2,
4307 fidl::encoding::DynamicFlags::empty(),
4308 )
4309 }
4310
4311 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
4312 /// after creating a collection. Clients can call this method to change
4313 /// when the log is printed. If multiple client set the deadline, it's
4314 /// unspecified which deadline will take effect.
4315 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
4316 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
4317 (deadline,),
4318 0x46d38f4772638867,
4319 fidl::encoding::DynamicFlags::empty(),
4320 )
4321 }
4322
4323 /// Verbose logging includes constraints set via SetConstraints() from each
4324 /// client along with info set via SetDebugClientInfo() and the structure of
4325 /// the tree of Node(s).
4326 ///
4327 /// Normally sysmem prints only a single line complaint when aggregation
4328 /// fails, with just the specific detailed reason that aggregation failed,
4329 /// with minimal context. While this is often enough to diagnose a problem
4330 /// if only a small change was made and the system had been working before
4331 /// the small change, it's often not particularly helpful for getting a new
4332 /// buffer collection to work for the first time. Especially with more
4333 /// complex trees of nodes, involving things like AttachToken(),
4334 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
4335 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
4336 /// looks like and why it's failing a logical allocation, or why a tree or
4337 /// sub-tree is failing sooner than expected.
4338 ///
4339 /// The intent of the extra logging is to be acceptable from a performance
4340 /// point of view, if only enabled on a low number of buffer collections.
4341 /// If we're not tracking down a bug, we shouldn't send this message.
4342 ///
4343 /// If too many participants leave verbose logging enabled, we may end up
4344 /// needing to require that system-wide sysmem verbose logging be permitted
4345 /// via some other setting, to avoid sysmem spamming the log too much due to
4346 /// this message.
4347 ///
4348 /// This may be a NOP for some nodes due to intentional policy associated
4349 /// with the node, if we don't trust a node enough to let it turn on verbose
4350 /// logging.
4351 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
4352 self.client.send::<fidl::encoding::EmptyPayload>(
4353 (),
4354 0x6bfbe2cf1701d288,
4355 fidl::encoding::DynamicFlags::empty(),
4356 )
4357 }
4358
4359 /// This gets an event handle that can be used as a parameter to
4360 /// IsAlternateFor() called on any Node. The client will not be granted the
4361 /// right to signal this event, as this handle should only be used as proof
4362 /// that the client obtained this handle from this Node.
4363 ///
4364 /// Because this is a get not a set, no Sync() is needed between the
4365 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
4366 /// potentially being on different channels.
4367 ///
4368 /// See also IsAlternateFor().
4369 pub fn r#get_node_ref(
4370 &self,
4371 ___deadline: zx::MonotonicInstant,
4372 ) -> Result<fidl::Event, fidl::Error> {
4373 let _response = self.client.send_query::<
4374 fidl::encoding::EmptyPayload,
4375 NodeGetNodeRefResponse,
4376 BufferCollectionTokenMarker,
4377 >(
4378 (),
4379 0x467b7c75c35c3b84,
4380 fidl::encoding::DynamicFlags::empty(),
4381 ___deadline,
4382 )?;
4383 Ok(_response.node_ref)
4384 }
4385
4386 /// This checks whether the calling node is in a subtree rooted at a
4387 /// different child token of a common parent BufferCollectionTokenGroup, in
4388 /// relation to the passed-in node_ref.
4389 ///
4390 /// This call is for assisting with admission control de-duplication, and
4391 /// with debugging.
4392 ///
4393 /// The node_ref must be obtained using GetNodeRef() of a
4394 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
4395 ///
4396 /// The node_ref can be a duplicated handle; it's not necessary to call
4397 /// GetNodeRef() for every call to IsAlternateFor().
4398 ///
4399 /// If a calling token may not actually be a valid token at all due to
4400 /// a potentially hostile/untrusted provider of the token, call
4401 /// ValidateBufferCollectionToken() first instead of potentially getting
4402 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
4403 /// token not being a real token (not really talking to sysmem). Another
4404 /// option is to call BindSharedCollection with this token first which also
4405 /// validates the token along with converting it to a BufferCollection, then
4406 /// call BufferCollection IsAlternateFor().
4407 ///
4408 /// error values:
4409 ///
4410 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
4411 /// buffer collection as the calling Node. Before logical allocation and
4412 /// within the same logical allocation sub-tree, this essentially means that
4413 /// the node_ref was never part of this logical buffer collection, since
4414 /// before logical allocation all node_refs that come into existence remain
4415 /// in existence at least until logical allocation (including Node(s) that
4416 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
4417 /// to be returned, this Node's channel needs to still be connected server
4418 /// side, which won't be the case if the whole logical allocation has
4419 /// failed. After logical allocation or in a different logical allocation
4420 /// sub-tree there are additional potential reasons for this error. For
4421 /// example a different logical allocation (separated from this Node(s)
4422 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
4423 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
4424 /// exist and may select a different child sub-tree than the sub-tree the
4425 /// node_ref is in causing deletion of the node_ref Node. The only time
4426 /// sysmem keeps a Node around after that Node has no corresponding channel
4427 /// is when Close() is used and the Node's sub-tree has not yet failed.
4428 /// Another reason for this error is if the node_ref is an eventpair handle
4429 /// with sufficient rights, but isn't actually a real node_ref obtained from
4430 /// GetNodeRef().
4431 ///
4432 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
4433 /// eventpair handle, or doesn't have the needed rights expected on a real
4434 /// node_ref.
4435 ///
4436 /// No other failing status codes are returned by this call. However,
4437 /// sysmem may add additional codes in future, so the client should have
4438 /// sensible default handling for any failing status code.
4439 ///
4440 /// On success, is_alternate has the following meaning:
4441 /// * true - The first parent node in common between the calling node and
4442 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
4443 /// the calling Node and the node_ref Node will _not_ have both their
4444 /// constraints apply - rather sysmem will choose one or the other of
4445 /// the constraints - never both. This is because only one child of
4446 /// a BufferCollectionTokenGroup is selected during logical allocation,
4447 /// with only that one child's sub-tree contributing to constraints
4448 /// aggregation.
4449 /// * false - The first parent node in common between the calling Node and
4450 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
4451 /// this means the first parent node in common is a
4452 /// BufferCollectionToken or BufferCollection (regardless of not
4453 /// Close()ed or Close()ed). This means that the calling Node and the
4454 /// node_ref Node _may_ have both their constraints apply during
4455 /// constraints aggregation of the logical allocation, if both Node(s)
4456 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
4457 /// In this case, there is no BufferCollectionTokenGroup that will
4458 /// directly prevent the two Node(s) from both being selected and their
4459 /// constraints both aggregated, but even when false, one or both
4460 /// Node(s) may still be eliminated from consideration if one or both
4461 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
4462 /// which selects a child sub-tree other than the sub-tree containing
4463 /// the calling Node or node_ref Node.
4464 pub fn r#is_alternate_for(
4465 &self,
4466 mut node_ref: fidl::Event,
4467 ___deadline: zx::MonotonicInstant,
4468 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
4469 let _response = self.client.send_query::<
4470 NodeIsAlternateForRequest,
4471 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
4472 BufferCollectionTokenMarker,
4473 >(
4474 (node_ref,),
4475 0x33a2a7aff2776c07,
4476 fidl::encoding::DynamicFlags::empty(),
4477 ___deadline,
4478 )?;
4479 Ok(_response.map(|x| x.is_alternate))
4480 }
4481
4482 /// This method can be used to add more participants prior to creating a
4483 /// shared BufferCollection. A new token will be returned for each entry in
4484 /// the `rights_attenuation_masks` array. The return value is the client
4485 /// ends of each new participant token.
4486 ///
4487 /// If the calling token may not actually be a valid token at all due to
4488 /// a potentially hostile/untrusted provider of the token, consider using
4489 /// ValidateBufferCollectionToken() first instead of potentially getting
4490 /// stuck indefinitely if DuplicateSync() never responds due to the calling
4491 /// token not being a real token.
4492 ///
4493 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
4494 /// after calling this method.
4495 ///
4496 /// All tokens must be turned in via BindSharedCollection() or Close() for a
4497 /// BufferCollection to be successfully created.
4498 ///
4499 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
4500 /// will be absent in the buffer VMO rights obtainable via the corresponding
4501 /// returned token. This allows an initiator or intermediary participant to
4502 /// attenuate the rights available to a participant. This does not allow a
4503 /// participant to gain rights that the participant doesn't already have.
4504 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
4505 /// attenuation should be applied.
4506 pub fn r#duplicate_sync(
4507 &self,
4508 mut rights_attenuation_masks: &[fidl::Rights],
4509 ___deadline: zx::MonotonicInstant,
4510 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error> {
4511 let _response = self.client.send_query::<
4512 BufferCollectionTokenDuplicateSyncRequest,
4513 BufferCollectionTokenDuplicateSyncResponse,
4514 BufferCollectionTokenMarker,
4515 >(
4516 (rights_attenuation_masks,),
4517 0x49ed7ab7cc19f18,
4518 fidl::encoding::DynamicFlags::empty(),
4519 ___deadline,
4520 )?;
4521 Ok(_response.tokens)
4522 }
4523
4524 /// This method can be used to add a participant prior to creating a shared
4525 /// BufferCollection. It should only be used instead of DuplicateSync in
4526 /// performance sensitive cases where it would be undesireable to wait for
4527 /// sysmem to respond as part of each duplicate.
4528 ///
4529 /// After sending one or more Duplicate() messages, and before sending the
4530 /// created tokens to other participants (or to other Allocator channels),
4531 /// the client should send a Sync() and wait for its response. The Sync()
4532 /// call can be made on the token, or on the BufferCollection obtained by
4533 /// passing this token to BindSharedCollection(). Either will ensure that
4534 /// the server knows about the tokens created via Duplicate() before the
4535 /// other participant sends the token to the server via separate Allocator
4536 /// channel.
4537 ///
4538 /// All tokens must be turned in via BindSharedCollection() or Close() for a
4539 /// BufferCollection to be successfully created.
4540 ///
4541 /// When a client calls BindSharedCollection() to turn in a
4542 /// BufferCollectionToken, the server will process all Duplicate() messages
4543 /// before closing down the BufferCollectionToken. This allows the client
4544 /// to Duplicate() and immediately turn in the BufferCollectionToken using
4545 /// BindSharedCollection, then later transfer the client end of token_request
4546 /// to another participant - the server will notice the existence of the
4547 /// token_request before considering this BufferCollectionToken fully closed.
4548 ///
4549 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
4550 /// absent in the buffer VMO rights obtainable via the client end of
4551 /// token_request. This allows an initiator or intermediary participant to
4552 /// attenuate the rights available to a participant. This does not allow a
4553 /// participant to gain rights that the participant doesn't already have.
4554 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
4555 /// attenuation should be applied.
4556 ///
4557 /// These values for rights_attenuation_mask result in no attenuation:
4558 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
4559 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
4560 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
4561 ///
4562 /// `token_request` is the server end of a BufferCollectionToken channel.
4563 /// The client end of this channel acts as another participant in creating the
4564 /// shared BufferCollection.
4565 pub fn r#duplicate(
4566 &self,
4567 mut rights_attenuation_mask: u32,
4568 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
4569 ) -> Result<(), fidl::Error> {
4570 self.client.send::<BufferCollectionTokenDuplicateRequest>(
4571 (rights_attenuation_mask, token_request),
4572 0x2f9f81bdde4b7292,
4573 fidl::encoding::DynamicFlags::empty(),
4574 )
4575 }
4576
4577 /// A dispensable token can fail after buffers are logically allocated
4578 /// without causing failure of its parent (if any).
4579 ///
4580 /// The dispensable token participates in constraints aggregation along with
4581 /// its parent before logical buffer allocation. If the dispensable token
4582 /// fails before buffers are logically allocated, the failure propagates to
4583 /// the dispensable token's parent.
4584 ///
4585 /// After buffers are logically allocated, failure of the dispensable token
4586 /// (or any child of the dispensable token) does not propagate to the
4587 /// dispensable token's parent. Failure does propagate from a normal
4588 /// child of a dispensable token to the dispensable token. Failure
4589 /// of a child is blocked from reaching its parent if the child is attached,
4590 /// or if the child is dispensable and the failure occurred after logical
4591 /// allocation.
4592 ///
4593 /// A dispensable token can be used in cases where a participant needs to
4594 /// provide constraints, but after buffers are allocated, the participant
4595 /// can fail without causing buffer collection failure from the parent's
4596 /// point of view.
4597 ///
4598 /// In contrast, AttachToken() can be used to create a token which does not
4599 /// participate in constraints aggregation with its parent, and whose
4600 /// failure at any time does not propagate to its parent, and whose delay
4601 /// providing constraints does not prevent the parent from completing its
4602 /// buffer allocation.
4603 ///
4604 /// An initiator may in some scenarios choose to initially use a dispensable
4605 /// token for a given instance of a participant, and then later if the first
4606 /// instance of that participant fails, a new second instance of that
4607 /// participant my be given a token created with AttachToken().
4608 ///
4609 /// If a client uses this message, the client should not rely on the
4610 /// client's own BufferCollectionToken or BufferCollection channel to close
4611 /// from the server end due to abrupt failure of any BufferCollectionToken
4612 /// or BufferCollection that the client has SetDispensable() and given out
4613 /// to another process. For this reason, the client should take extra care
4614 /// to notice failure of that other process via other means.
4615 ///
4616 /// While it is possible (and potentially useful) to SetDispensable() on a
4617 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
4618 /// replace a failed dispensable token that was a direct child of a group
4619 /// with a new token using AttachToken() (since there's no AttachToken() on
4620 /// a group). Instead, to enable AttachToken() replacement in this case,
4621 /// create an additional non-dispensable token (node) that's a direct child
4622 /// of the group and make the existing dispensable token a child of the
4623 /// additional token (node). This way, the additional token (node) that is
4624 /// a direct child of the group has BufferCollection.AttachToken() which can
4625 /// be used to replace the failed dispensable token.
4626 ///
4627 /// SetDispensable() on an already-dispensable token is idempotent.
4628 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
4629 self.client.send::<fidl::encoding::EmptyPayload>(
4630 (),
4631 0x76e4ec34fc2cf5b3,
4632 fidl::encoding::DynamicFlags::empty(),
4633 )
4634 }
4635
4636 /// Most sysmem clients and many participants don't need to care about this
4637 /// message or about BufferCollectionTokenGroup(s) in general.
4638 ///
4639 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
4640 /// tokens. The child tokens which are not selected during aggregation will
4641 /// fail (close), which a potential participant should notice when their
4642 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
4643 /// participant to clean up the speculative usage that didn't end up
4644 /// happening (similarly to a normal BufferCollection server end closing
4645 /// on failure of a logical buffer collection).
4646 ///
4647 /// See comments on protocol BufferCollectionTokenGroup.
4648 ///
4649 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
4650 /// applied to the whole group can be achieved with a token for this purpose
4651 /// as a direct parent of the group.
4652 ///
4653 /// group_request - the server end of a BufferCollectionTokenGroup channel
4654 /// to be served by sysmem.
4655 pub fn r#create_buffer_collection_token_group(
4656 &self,
4657 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
4658 ) -> Result<(), fidl::Error> {
4659 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
4660 (group_request,),
4661 0x2f6243e05f22b9a7,
4662 fidl::encoding::DynamicFlags::empty(),
4663 )
4664 }
4665}
4666
4667#[cfg(target_os = "fuchsia")]
4668impl From<BufferCollectionTokenSynchronousProxy> for zx::NullableHandle {
4669 fn from(value: BufferCollectionTokenSynchronousProxy) -> Self {
4670 value.into_channel().into()
4671 }
4672}
4673
4674#[cfg(target_os = "fuchsia")]
4675impl From<fidl::Channel> for BufferCollectionTokenSynchronousProxy {
4676 fn from(value: fidl::Channel) -> Self {
4677 Self::new(value)
4678 }
4679}
4680
4681#[cfg(target_os = "fuchsia")]
4682impl fidl::endpoints::FromClient for BufferCollectionTokenSynchronousProxy {
4683 type Protocol = BufferCollectionTokenMarker;
4684
4685 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>) -> Self {
4686 Self::new(value.into_channel())
4687 }
4688}
4689
4690#[derive(Debug, Clone)]
4691pub struct BufferCollectionTokenProxy {
4692 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
4693}
4694
4695impl fidl::endpoints::Proxy for BufferCollectionTokenProxy {
4696 type Protocol = BufferCollectionTokenMarker;
4697
4698 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
4699 Self::new(inner)
4700 }
4701
4702 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
4703 self.client.into_channel().map_err(|client| Self { client })
4704 }
4705
4706 fn as_channel(&self) -> &::fidl::AsyncChannel {
4707 self.client.as_channel()
4708 }
4709}
4710
4711impl BufferCollectionTokenProxy {
4712 /// Create a new Proxy for fuchsia.sysmem/BufferCollectionToken.
4713 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
4714 let protocol_name =
4715 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
4716 Self { client: fidl::client::Client::new(channel, protocol_name) }
4717 }
4718
4719 /// Get a Stream of events from the remote end of the protocol.
4720 ///
4721 /// # Panics
4722 ///
4723 /// Panics if the event stream was already taken.
4724 pub fn take_event_stream(&self) -> BufferCollectionTokenEventStream {
4725 BufferCollectionTokenEventStream { event_receiver: self.client.take_event_receiver() }
4726 }
4727
4728 /// Ensure that previous messages, including Duplicate() messages on a
4729 /// token, collection, or group, have been received server side.
4730 ///
4731 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
4732 /// valid sysmem token risks the Sync() hanging forever. See
4733 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
4734 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
4735 /// Another way is to pass the token to BindSharedCollection(), which also
4736 /// validates the token as part of exchanging it for a BufferCollection
4737 /// channel, and BufferCollection Sync() can then be used.
4738 ///
4739 /// After a Sync(), it's then safe to send the client end of token_request
4740 /// to another participant knowing the server will recognize the token when
4741 /// it's sent into BindSharedCollection() by the other participant.
4742 ///
4743 /// Other options include waiting for each token.Duplicate() to complete
4744 /// individually (using separate call to token.Sync() after each), or
4745 /// calling Sync() on BufferCollection after the token has been turned in
4746 /// via BindSharedCollection().
4747 ///
4748 /// Another way to mitigate is to avoid calling Sync() on the token, and
4749 /// instead later deal with potential failure of BufferCollection.Sync() if
4750 /// the original token was invalid. This option can be preferable from a
4751 /// performance point of view, but requires client code to delay sending
4752 /// tokens duplicated from this token until after client code has converted
4753 /// the duplicating token to a BufferCollection and received successful
4754 /// response from BufferCollection.Sync().
4755 ///
4756 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
4757 /// When BufferCollection.Sync() isn't feasible, the caller must already
4758 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
4759 /// hang forever. See ValidateBufferCollectionToken() to check token
4760 /// validity first if the token isn't already known to be (is/was) valid.
4761 pub fn r#sync(
4762 &self,
4763 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
4764 BufferCollectionTokenProxyInterface::r#sync(self)
4765 }
4766
4767 /// On a BufferCollectionToken channel:
4768 ///
4769 /// Normally a participant will convert a BufferCollectionToken into a
4770 /// BufferCollection view, but a participant is also free to Close() the
4771 /// token (and then close the channel immediately or shortly later in
4772 /// response to server closing its end), which avoids causing logical buffer
4773 /// collection failure. Â Normally an unexpected token channel close will
4774 /// cause logical buffer collection failure (the only exceptions being
4775 /// certain cases involving AttachToken() or SetDispensable()).
4776 ///
4777 /// On a BufferCollection channel:
4778 ///
4779 /// By default the server handles unexpected failure of a BufferCollection
4780 /// by failing the whole logical buffer collection. Partly this is to
4781 /// expedite closing VMO handles to reclaim memory when any participant
4782 /// fails. If a participant would like to cleanly close a BufferCollection
4783 /// view without causing logical buffer collection failure, the participant
4784 /// can send Close() before closing the client end of the BufferCollection
4785 /// channel. If this is the last BufferCollection view, the logical buffer
4786 /// collection will still go away. The Close() can occur before or after
4787 /// SetConstraints(). If before SetConstraints(), the buffer collection
4788 /// won't require constraints from this node in order to allocate. If
4789 /// after SetConstraints(), the constraints are retained and aggregated
4790 /// along with any subsequent logical allocation(s), despite the lack of
4791 /// channel connection.
4792 ///
4793 /// On a BufferCollectionTokenGroup channel:
4794 ///
4795 /// By default, unexpected failure of a BufferCollectionTokenGroup will
4796 /// trigger failure of the logical BufferCollectionTokenGroup and will
4797 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
4798 /// channel without failing the logical group or propagating failure, send
4799 /// Close() before closing the channel client endpoint.
4800 ///
4801 /// If Close() occurs before AllChildrenPresent(), the logical buffer
4802 /// collection will still fail despite the Close() (because sysmem can't be
4803 /// sure whether all relevant children were created, so it's ambiguous
4804 /// whether all relevant constraints will be provided to sysmem). If
4805 /// Close() occurs after AllChildrenPresent(), the children and all their
4806 /// constraints remain intact (just as they would if the
4807 /// BufferCollectionTokenGroup channel had remained open), and the close
4808 /// doesn't trigger or propagate failure.
4809 pub fn r#close(&self) -> Result<(), fidl::Error> {
4810 BufferCollectionTokenProxyInterface::r#close(self)
4811 }
4812
4813 /// Set a name for VMOs in this buffer collection. The name may be truncated
4814 /// shorter. The name only affects VMOs allocated after it's set - this call
4815 /// does not rename existing VMOs. If multiple clients set different names
4816 /// then the larger priority value will win.
4817 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
4818 BufferCollectionTokenProxyInterface::r#set_name(self, priority, name)
4819 }
4820
4821 /// Set information about the current client that can be used by sysmem to
4822 /// help debug leaking memory and hangs waiting for constraints. |name| can
4823 /// be an arbitrary string, but the current process name (see
4824 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
4825 /// arbitrary id, but the current process ID (see
4826 /// fsl::GetCurrentProcessKoid()) is a good default.
4827 ///
4828 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
4829 /// indicate which client is closing their channel first, leading to
4830 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
4831 /// over, but if happening earlier than expected, the
4832 /// client-channel-specific name can help diagnose where the failure is
4833 /// first coming from, from sysmem's point of view).
4834 ///
4835 /// By default (unless overriden by this message or using
4836 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
4837 /// parent Node at the time the child Node is created. While this can be
4838 /// better than nothing, it's often better for each participant to use
4839 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
4840 /// info directly relevant to the current client. Also, SetVerboseLogging()
4841 /// can be used to help disambiguate if a Node is suspected of having info
4842 /// that was copied from its parent.
4843 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
4844 BufferCollectionTokenProxyInterface::r#set_debug_client_info(self, name, id)
4845 }
4846
4847 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
4848 /// after creating a collection. Clients can call this method to change
4849 /// when the log is printed. If multiple client set the deadline, it's
4850 /// unspecified which deadline will take effect.
4851 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
4852 BufferCollectionTokenProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
4853 }
4854
4855 /// Verbose logging includes constraints set via SetConstraints() from each
4856 /// client along with info set via SetDebugClientInfo() and the structure of
4857 /// the tree of Node(s).
4858 ///
4859 /// Normally sysmem prints only a single line complaint when aggregation
4860 /// fails, with just the specific detailed reason that aggregation failed,
4861 /// with minimal context. While this is often enough to diagnose a problem
4862 /// if only a small change was made and the system had been working before
4863 /// the small change, it's often not particularly helpful for getting a new
4864 /// buffer collection to work for the first time. Especially with more
4865 /// complex trees of nodes, involving things like AttachToken(),
4866 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
4867 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
4868 /// looks like and why it's failing a logical allocation, or why a tree or
4869 /// sub-tree is failing sooner than expected.
4870 ///
4871 /// The intent of the extra logging is to be acceptable from a performance
4872 /// point of view, if only enabled on a low number of buffer collections.
4873 /// If we're not tracking down a bug, we shouldn't send this message.
4874 ///
4875 /// If too many participants leave verbose logging enabled, we may end up
4876 /// needing to require that system-wide sysmem verbose logging be permitted
4877 /// via some other setting, to avoid sysmem spamming the log too much due to
4878 /// this message.
4879 ///
4880 /// This may be a NOP for some nodes due to intentional policy associated
4881 /// with the node, if we don't trust a node enough to let it turn on verbose
4882 /// logging.
4883 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
4884 BufferCollectionTokenProxyInterface::r#set_verbose_logging(self)
4885 }
4886
4887 /// This gets an event handle that can be used as a parameter to
4888 /// IsAlternateFor() called on any Node. The client will not be granted the
4889 /// right to signal this event, as this handle should only be used as proof
4890 /// that the client obtained this handle from this Node.
4891 ///
4892 /// Because this is a get not a set, no Sync() is needed between the
4893 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
4894 /// potentially being on different channels.
4895 ///
4896 /// See also IsAlternateFor().
4897 pub fn r#get_node_ref(
4898 &self,
4899 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
4900 {
4901 BufferCollectionTokenProxyInterface::r#get_node_ref(self)
4902 }
4903
4904 /// This checks whether the calling node is in a subtree rooted at a
4905 /// different child token of a common parent BufferCollectionTokenGroup, in
4906 /// relation to the passed-in node_ref.
4907 ///
4908 /// This call is for assisting with admission control de-duplication, and
4909 /// with debugging.
4910 ///
4911 /// The node_ref must be obtained using GetNodeRef() of a
4912 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
4913 ///
4914 /// The node_ref can be a duplicated handle; it's not necessary to call
4915 /// GetNodeRef() for every call to IsAlternateFor().
4916 ///
4917 /// If a calling token may not actually be a valid token at all due to
4918 /// a potentially hostile/untrusted provider of the token, call
4919 /// ValidateBufferCollectionToken() first instead of potentially getting
4920 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
4921 /// token not being a real token (not really talking to sysmem). Another
4922 /// option is to call BindSharedCollection with this token first which also
4923 /// validates the token along with converting it to a BufferCollection, then
4924 /// call BufferCollection IsAlternateFor().
4925 ///
4926 /// error values:
4927 ///
4928 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
4929 /// buffer collection as the calling Node. Before logical allocation and
4930 /// within the same logical allocation sub-tree, this essentially means that
4931 /// the node_ref was never part of this logical buffer collection, since
4932 /// before logical allocation all node_refs that come into existence remain
4933 /// in existence at least until logical allocation (including Node(s) that
4934 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
4935 /// to be returned, this Node's channel needs to still be connected server
4936 /// side, which won't be the case if the whole logical allocation has
4937 /// failed. After logical allocation or in a different logical allocation
4938 /// sub-tree there are additional potential reasons for this error. For
4939 /// example a different logical allocation (separated from this Node(s)
4940 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
4941 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
4942 /// exist and may select a different child sub-tree than the sub-tree the
4943 /// node_ref is in causing deletion of the node_ref Node. The only time
4944 /// sysmem keeps a Node around after that Node has no corresponding channel
4945 /// is when Close() is used and the Node's sub-tree has not yet failed.
4946 /// Another reason for this error is if the node_ref is an eventpair handle
4947 /// with sufficient rights, but isn't actually a real node_ref obtained from
4948 /// GetNodeRef().
4949 ///
4950 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
4951 /// eventpair handle, or doesn't have the needed rights expected on a real
4952 /// node_ref.
4953 ///
4954 /// No other failing status codes are returned by this call. However,
4955 /// sysmem may add additional codes in future, so the client should have
4956 /// sensible default handling for any failing status code.
4957 ///
4958 /// On success, is_alternate has the following meaning:
4959 /// * true - The first parent node in common between the calling node and
4960 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
4961 /// the calling Node and the node_ref Node will _not_ have both their
4962 /// constraints apply - rather sysmem will choose one or the other of
4963 /// the constraints - never both. This is because only one child of
4964 /// a BufferCollectionTokenGroup is selected during logical allocation,
4965 /// with only that one child's sub-tree contributing to constraints
4966 /// aggregation.
4967 /// * false - The first parent node in common between the calling Node and
4968 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
4969 /// this means the first parent node in common is a
4970 /// BufferCollectionToken or BufferCollection (regardless of not
4971 /// Close()ed or Close()ed). This means that the calling Node and the
4972 /// node_ref Node _may_ have both their constraints apply during
4973 /// constraints aggregation of the logical allocation, if both Node(s)
4974 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
4975 /// In this case, there is no BufferCollectionTokenGroup that will
4976 /// directly prevent the two Node(s) from both being selected and their
4977 /// constraints both aggregated, but even when false, one or both
4978 /// Node(s) may still be eliminated from consideration if one or both
4979 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
4980 /// which selects a child sub-tree other than the sub-tree containing
4981 /// the calling Node or node_ref Node.
4982 pub fn r#is_alternate_for(
4983 &self,
4984 mut node_ref: fidl::Event,
4985 ) -> fidl::client::QueryResponseFut<
4986 NodeIsAlternateForResult,
4987 fidl::encoding::DefaultFuchsiaResourceDialect,
4988 > {
4989 BufferCollectionTokenProxyInterface::r#is_alternate_for(self, node_ref)
4990 }
4991
4992 /// This method can be used to add more participants prior to creating a
4993 /// shared BufferCollection. A new token will be returned for each entry in
4994 /// the `rights_attenuation_masks` array. The return value is the client
4995 /// ends of each new participant token.
4996 ///
4997 /// If the calling token may not actually be a valid token at all due to
4998 /// a potentially hostile/untrusted provider of the token, consider using
4999 /// ValidateBufferCollectionToken() first instead of potentially getting
5000 /// stuck indefinitely if DuplicateSync() never responds due to the calling
5001 /// token not being a real token.
5002 ///
5003 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
5004 /// after calling this method.
5005 ///
5006 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5007 /// BufferCollection to be successfully created.
5008 ///
5009 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
5010 /// will be absent in the buffer VMO rights obtainable via the corresponding
5011 /// returned token. This allows an initiator or intermediary participant to
5012 /// attenuate the rights available to a participant. This does not allow a
5013 /// participant to gain rights that the participant doesn't already have.
5014 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5015 /// attenuation should be applied.
5016 pub fn r#duplicate_sync(
5017 &self,
5018 mut rights_attenuation_masks: &[fidl::Rights],
5019 ) -> fidl::client::QueryResponseFut<
5020 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
5021 fidl::encoding::DefaultFuchsiaResourceDialect,
5022 > {
5023 BufferCollectionTokenProxyInterface::r#duplicate_sync(self, rights_attenuation_masks)
5024 }
5025
5026 /// This method can be used to add a participant prior to creating a shared
5027 /// BufferCollection. It should only be used instead of DuplicateSync in
5028 /// performance sensitive cases where it would be undesireable to wait for
5029 /// sysmem to respond as part of each duplicate.
5030 ///
5031 /// After sending one or more Duplicate() messages, and before sending the
5032 /// created tokens to other participants (or to other Allocator channels),
5033 /// the client should send a Sync() and wait for its response. The Sync()
5034 /// call can be made on the token, or on the BufferCollection obtained by
5035 /// passing this token to BindSharedCollection(). Either will ensure that
5036 /// the server knows about the tokens created via Duplicate() before the
5037 /// other participant sends the token to the server via separate Allocator
5038 /// channel.
5039 ///
5040 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5041 /// BufferCollection to be successfully created.
5042 ///
5043 /// When a client calls BindSharedCollection() to turn in a
5044 /// BufferCollectionToken, the server will process all Duplicate() messages
5045 /// before closing down the BufferCollectionToken. This allows the client
5046 /// to Duplicate() and immediately turn in the BufferCollectionToken using
5047 /// BindSharedCollection, then later transfer the client end of token_request
5048 /// to another participant - the server will notice the existence of the
5049 /// token_request before considering this BufferCollectionToken fully closed.
5050 ///
5051 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
5052 /// absent in the buffer VMO rights obtainable via the client end of
5053 /// token_request. This allows an initiator or intermediary participant to
5054 /// attenuate the rights available to a participant. This does not allow a
5055 /// participant to gain rights that the participant doesn't already have.
5056 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5057 /// attenuation should be applied.
5058 ///
5059 /// These values for rights_attenuation_mask result in no attenuation:
5060 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
5061 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
5062 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
5063 ///
5064 /// `token_request` is the server end of a BufferCollectionToken channel.
5065 /// The client end of this channel acts as another participant in creating the
5066 /// shared BufferCollection.
5067 pub fn r#duplicate(
5068 &self,
5069 mut rights_attenuation_mask: u32,
5070 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5071 ) -> Result<(), fidl::Error> {
5072 BufferCollectionTokenProxyInterface::r#duplicate(
5073 self,
5074 rights_attenuation_mask,
5075 token_request,
5076 )
5077 }
5078
5079 /// A dispensable token can fail after buffers are logically allocated
5080 /// without causing failure of its parent (if any).
5081 ///
5082 /// The dispensable token participates in constraints aggregation along with
5083 /// its parent before logical buffer allocation. If the dispensable token
5084 /// fails before buffers are logically allocated, the failure propagates to
5085 /// the dispensable token's parent.
5086 ///
5087 /// After buffers are logically allocated, failure of the dispensable token
5088 /// (or any child of the dispensable token) does not propagate to the
5089 /// dispensable token's parent. Failure does propagate from a normal
5090 /// child of a dispensable token to the dispensable token. Failure
5091 /// of a child is blocked from reaching its parent if the child is attached,
5092 /// or if the child is dispensable and the failure occurred after logical
5093 /// allocation.
5094 ///
5095 /// A dispensable token can be used in cases where a participant needs to
5096 /// provide constraints, but after buffers are allocated, the participant
5097 /// can fail without causing buffer collection failure from the parent's
5098 /// point of view.
5099 ///
5100 /// In contrast, AttachToken() can be used to create a token which does not
5101 /// participate in constraints aggregation with its parent, and whose
5102 /// failure at any time does not propagate to its parent, and whose delay
5103 /// providing constraints does not prevent the parent from completing its
5104 /// buffer allocation.
5105 ///
5106 /// An initiator may in some scenarios choose to initially use a dispensable
5107 /// token for a given instance of a participant, and then later if the first
5108 /// instance of that participant fails, a new second instance of that
5109 /// participant my be given a token created with AttachToken().
5110 ///
5111 /// If a client uses this message, the client should not rely on the
5112 /// client's own BufferCollectionToken or BufferCollection channel to close
5113 /// from the server end due to abrupt failure of any BufferCollectionToken
5114 /// or BufferCollection that the client has SetDispensable() and given out
5115 /// to another process. For this reason, the client should take extra care
5116 /// to notice failure of that other process via other means.
5117 ///
5118 /// While it is possible (and potentially useful) to SetDispensable() on a
5119 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
5120 /// replace a failed dispensable token that was a direct child of a group
5121 /// with a new token using AttachToken() (since there's no AttachToken() on
5122 /// a group). Instead, to enable AttachToken() replacement in this case,
5123 /// create an additional non-dispensable token (node) that's a direct child
5124 /// of the group and make the existing dispensable token a child of the
5125 /// additional token (node). This way, the additional token (node) that is
5126 /// a direct child of the group has BufferCollection.AttachToken() which can
5127 /// be used to replace the failed dispensable token.
5128 ///
5129 /// SetDispensable() on an already-dispensable token is idempotent.
5130 pub fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
5131 BufferCollectionTokenProxyInterface::r#set_dispensable(self)
5132 }
5133
5134 /// Most sysmem clients and many participants don't need to care about this
5135 /// message or about BufferCollectionTokenGroup(s) in general.
5136 ///
5137 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
5138 /// tokens. The child tokens which are not selected during aggregation will
5139 /// fail (close), which a potential participant should notice when their
5140 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
5141 /// participant to clean up the speculative usage that didn't end up
5142 /// happening (similarly to a normal BufferCollection server end closing
5143 /// on failure of a logical buffer collection).
5144 ///
5145 /// See comments on protocol BufferCollectionTokenGroup.
5146 ///
5147 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
5148 /// applied to the whole group can be achieved with a token for this purpose
5149 /// as a direct parent of the group.
5150 ///
5151 /// group_request - the server end of a BufferCollectionTokenGroup channel
5152 /// to be served by sysmem.
5153 pub fn r#create_buffer_collection_token_group(
5154 &self,
5155 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
5156 ) -> Result<(), fidl::Error> {
5157 BufferCollectionTokenProxyInterface::r#create_buffer_collection_token_group(
5158 self,
5159 group_request,
5160 )
5161 }
5162}
5163
5164impl BufferCollectionTokenProxyInterface for BufferCollectionTokenProxy {
5165 type SyncResponseFut =
5166 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
5167 fn r#sync(&self) -> Self::SyncResponseFut {
5168 fn _decode(
5169 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5170 ) -> Result<(), fidl::Error> {
5171 let _response = fidl::client::decode_transaction_body::<
5172 fidl::encoding::EmptyPayload,
5173 fidl::encoding::DefaultFuchsiaResourceDialect,
5174 0x4577e238ae26291,
5175 >(_buf?)?;
5176 Ok(_response)
5177 }
5178 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
5179 (),
5180 0x4577e238ae26291,
5181 fidl::encoding::DynamicFlags::empty(),
5182 _decode,
5183 )
5184 }
5185
5186 fn r#close(&self) -> Result<(), fidl::Error> {
5187 self.client.send::<fidl::encoding::EmptyPayload>(
5188 (),
5189 0x5b1d7a4f5681fca7,
5190 fidl::encoding::DynamicFlags::empty(),
5191 )
5192 }
5193
5194 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
5195 self.client.send::<NodeSetNameRequest>(
5196 (priority, name),
5197 0x77a41bb6217e2443,
5198 fidl::encoding::DynamicFlags::empty(),
5199 )
5200 }
5201
5202 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
5203 self.client.send::<NodeSetDebugClientInfoRequest>(
5204 (name, id),
5205 0x7275759070eb5ee2,
5206 fidl::encoding::DynamicFlags::empty(),
5207 )
5208 }
5209
5210 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
5211 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
5212 (deadline,),
5213 0x46d38f4772638867,
5214 fidl::encoding::DynamicFlags::empty(),
5215 )
5216 }
5217
5218 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
5219 self.client.send::<fidl::encoding::EmptyPayload>(
5220 (),
5221 0x6bfbe2cf1701d288,
5222 fidl::encoding::DynamicFlags::empty(),
5223 )
5224 }
5225
5226 type GetNodeRefResponseFut =
5227 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
5228 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
5229 fn _decode(
5230 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5231 ) -> Result<fidl::Event, fidl::Error> {
5232 let _response = fidl::client::decode_transaction_body::<
5233 NodeGetNodeRefResponse,
5234 fidl::encoding::DefaultFuchsiaResourceDialect,
5235 0x467b7c75c35c3b84,
5236 >(_buf?)?;
5237 Ok(_response.node_ref)
5238 }
5239 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
5240 (),
5241 0x467b7c75c35c3b84,
5242 fidl::encoding::DynamicFlags::empty(),
5243 _decode,
5244 )
5245 }
5246
5247 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
5248 NodeIsAlternateForResult,
5249 fidl::encoding::DefaultFuchsiaResourceDialect,
5250 >;
5251 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
5252 fn _decode(
5253 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5254 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
5255 let _response = fidl::client::decode_transaction_body::<
5256 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
5257 fidl::encoding::DefaultFuchsiaResourceDialect,
5258 0x33a2a7aff2776c07,
5259 >(_buf?)?;
5260 Ok(_response.map(|x| x.is_alternate))
5261 }
5262 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
5263 (node_ref,),
5264 0x33a2a7aff2776c07,
5265 fidl::encoding::DynamicFlags::empty(),
5266 _decode,
5267 )
5268 }
5269
5270 type DuplicateSyncResponseFut = fidl::client::QueryResponseFut<
5271 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
5272 fidl::encoding::DefaultFuchsiaResourceDialect,
5273 >;
5274 fn r#duplicate_sync(
5275 &self,
5276 mut rights_attenuation_masks: &[fidl::Rights],
5277 ) -> Self::DuplicateSyncResponseFut {
5278 fn _decode(
5279 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
5280 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error>
5281 {
5282 let _response = fidl::client::decode_transaction_body::<
5283 BufferCollectionTokenDuplicateSyncResponse,
5284 fidl::encoding::DefaultFuchsiaResourceDialect,
5285 0x49ed7ab7cc19f18,
5286 >(_buf?)?;
5287 Ok(_response.tokens)
5288 }
5289 self.client.send_query_and_decode::<
5290 BufferCollectionTokenDuplicateSyncRequest,
5291 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
5292 >(
5293 (rights_attenuation_masks,),
5294 0x49ed7ab7cc19f18,
5295 fidl::encoding::DynamicFlags::empty(),
5296 _decode,
5297 )
5298 }
5299
5300 fn r#duplicate(
5301 &self,
5302 mut rights_attenuation_mask: u32,
5303 mut token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5304 ) -> Result<(), fidl::Error> {
5305 self.client.send::<BufferCollectionTokenDuplicateRequest>(
5306 (rights_attenuation_mask, token_request),
5307 0x2f9f81bdde4b7292,
5308 fidl::encoding::DynamicFlags::empty(),
5309 )
5310 }
5311
5312 fn r#set_dispensable(&self) -> Result<(), fidl::Error> {
5313 self.client.send::<fidl::encoding::EmptyPayload>(
5314 (),
5315 0x76e4ec34fc2cf5b3,
5316 fidl::encoding::DynamicFlags::empty(),
5317 )
5318 }
5319
5320 fn r#create_buffer_collection_token_group(
5321 &self,
5322 mut group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
5323 ) -> Result<(), fidl::Error> {
5324 self.client.send::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
5325 (group_request,),
5326 0x2f6243e05f22b9a7,
5327 fidl::encoding::DynamicFlags::empty(),
5328 )
5329 }
5330}
5331
5332pub struct BufferCollectionTokenEventStream {
5333 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
5334}
5335
5336impl std::marker::Unpin for BufferCollectionTokenEventStream {}
5337
5338impl futures::stream::FusedStream for BufferCollectionTokenEventStream {
5339 fn is_terminated(&self) -> bool {
5340 self.event_receiver.is_terminated()
5341 }
5342}
5343
5344impl futures::Stream for BufferCollectionTokenEventStream {
5345 type Item = Result<BufferCollectionTokenEvent, fidl::Error>;
5346
5347 fn poll_next(
5348 mut self: std::pin::Pin<&mut Self>,
5349 cx: &mut std::task::Context<'_>,
5350 ) -> std::task::Poll<Option<Self::Item>> {
5351 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
5352 &mut self.event_receiver,
5353 cx
5354 )?) {
5355 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenEvent::decode(buf))),
5356 None => std::task::Poll::Ready(None),
5357 }
5358 }
5359}
5360
5361#[derive(Debug)]
5362pub enum BufferCollectionTokenEvent {}
5363
5364impl BufferCollectionTokenEvent {
5365 /// Decodes a message buffer as a [`BufferCollectionTokenEvent`].
5366 fn decode(
5367 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
5368 ) -> Result<BufferCollectionTokenEvent, fidl::Error> {
5369 let (bytes, _handles) = buf.split_mut();
5370 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
5371 debug_assert_eq!(tx_header.tx_id, 0);
5372 match tx_header.ordinal {
5373 _ => Err(fidl::Error::UnknownOrdinal {
5374 ordinal: tx_header.ordinal,
5375 protocol_name:
5376 <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
5377 }),
5378 }
5379 }
5380}
5381
5382/// A Stream of incoming requests for fuchsia.sysmem/BufferCollectionToken.
5383pub struct BufferCollectionTokenRequestStream {
5384 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
5385 is_terminated: bool,
5386}
5387
5388impl std::marker::Unpin for BufferCollectionTokenRequestStream {}
5389
5390impl futures::stream::FusedStream for BufferCollectionTokenRequestStream {
5391 fn is_terminated(&self) -> bool {
5392 self.is_terminated
5393 }
5394}
5395
5396impl fidl::endpoints::RequestStream for BufferCollectionTokenRequestStream {
5397 type Protocol = BufferCollectionTokenMarker;
5398 type ControlHandle = BufferCollectionTokenControlHandle;
5399
5400 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
5401 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
5402 }
5403
5404 fn control_handle(&self) -> Self::ControlHandle {
5405 BufferCollectionTokenControlHandle { inner: self.inner.clone() }
5406 }
5407
5408 fn into_inner(
5409 self,
5410 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
5411 {
5412 (self.inner, self.is_terminated)
5413 }
5414
5415 fn from_inner(
5416 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
5417 is_terminated: bool,
5418 ) -> Self {
5419 Self { inner, is_terminated }
5420 }
5421}
5422
5423impl futures::Stream for BufferCollectionTokenRequestStream {
5424 type Item = Result<BufferCollectionTokenRequest, fidl::Error>;
5425
5426 fn poll_next(
5427 mut self: std::pin::Pin<&mut Self>,
5428 cx: &mut std::task::Context<'_>,
5429 ) -> std::task::Poll<Option<Self::Item>> {
5430 let this = &mut *self;
5431 if this.inner.check_shutdown(cx) {
5432 this.is_terminated = true;
5433 return std::task::Poll::Ready(None);
5434 }
5435 if this.is_terminated {
5436 panic!("polled BufferCollectionTokenRequestStream after completion");
5437 }
5438 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
5439 |bytes, handles| {
5440 match this.inner.channel().read_etc(cx, bytes, handles) {
5441 std::task::Poll::Ready(Ok(())) => {}
5442 std::task::Poll::Pending => return std::task::Poll::Pending,
5443 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
5444 this.is_terminated = true;
5445 return std::task::Poll::Ready(None);
5446 }
5447 std::task::Poll::Ready(Err(e)) => {
5448 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
5449 e.into(),
5450 ))));
5451 }
5452 }
5453
5454 // A message has been received from the channel
5455 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
5456
5457 std::task::Poll::Ready(Some(match header.ordinal {
5458 0x4577e238ae26291 => {
5459 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5460 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5461 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5462 let control_handle = BufferCollectionTokenControlHandle {
5463 inner: this.inner.clone(),
5464 };
5465 Ok(BufferCollectionTokenRequest::Sync {
5466 responder: BufferCollectionTokenSyncResponder {
5467 control_handle: std::mem::ManuallyDrop::new(control_handle),
5468 tx_id: header.tx_id,
5469 },
5470 })
5471 }
5472 0x5b1d7a4f5681fca7 => {
5473 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5474 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5475 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5476 let control_handle = BufferCollectionTokenControlHandle {
5477 inner: this.inner.clone(),
5478 };
5479 Ok(BufferCollectionTokenRequest::Close {
5480 control_handle,
5481 })
5482 }
5483 0x77a41bb6217e2443 => {
5484 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5485 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5486 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
5487 let control_handle = BufferCollectionTokenControlHandle {
5488 inner: this.inner.clone(),
5489 };
5490 Ok(BufferCollectionTokenRequest::SetName {priority: req.priority,
5491name: req.name,
5492
5493 control_handle,
5494 })
5495 }
5496 0x7275759070eb5ee2 => {
5497 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5498 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5499 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
5500 let control_handle = BufferCollectionTokenControlHandle {
5501 inner: this.inner.clone(),
5502 };
5503 Ok(BufferCollectionTokenRequest::SetDebugClientInfo {name: req.name,
5504id: req.id,
5505
5506 control_handle,
5507 })
5508 }
5509 0x46d38f4772638867 => {
5510 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5511 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5512 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
5513 let control_handle = BufferCollectionTokenControlHandle {
5514 inner: this.inner.clone(),
5515 };
5516 Ok(BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {deadline: req.deadline,
5517
5518 control_handle,
5519 })
5520 }
5521 0x6bfbe2cf1701d288 => {
5522 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5523 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5524 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5525 let control_handle = BufferCollectionTokenControlHandle {
5526 inner: this.inner.clone(),
5527 };
5528 Ok(BufferCollectionTokenRequest::SetVerboseLogging {
5529 control_handle,
5530 })
5531 }
5532 0x467b7c75c35c3b84 => {
5533 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5534 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5535 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5536 let control_handle = BufferCollectionTokenControlHandle {
5537 inner: this.inner.clone(),
5538 };
5539 Ok(BufferCollectionTokenRequest::GetNodeRef {
5540 responder: BufferCollectionTokenGetNodeRefResponder {
5541 control_handle: std::mem::ManuallyDrop::new(control_handle),
5542 tx_id: header.tx_id,
5543 },
5544 })
5545 }
5546 0x33a2a7aff2776c07 => {
5547 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5548 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5549 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
5550 let control_handle = BufferCollectionTokenControlHandle {
5551 inner: this.inner.clone(),
5552 };
5553 Ok(BufferCollectionTokenRequest::IsAlternateFor {node_ref: req.node_ref,
5554
5555 responder: BufferCollectionTokenIsAlternateForResponder {
5556 control_handle: std::mem::ManuallyDrop::new(control_handle),
5557 tx_id: header.tx_id,
5558 },
5559 })
5560 }
5561 0x49ed7ab7cc19f18 => {
5562 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
5563 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5564 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateSyncRequest>(&header, _body_bytes, handles, &mut req)?;
5565 let control_handle = BufferCollectionTokenControlHandle {
5566 inner: this.inner.clone(),
5567 };
5568 Ok(BufferCollectionTokenRequest::DuplicateSync {rights_attenuation_masks: req.rights_attenuation_masks,
5569
5570 responder: BufferCollectionTokenDuplicateSyncResponder {
5571 control_handle: std::mem::ManuallyDrop::new(control_handle),
5572 tx_id: header.tx_id,
5573 },
5574 })
5575 }
5576 0x2f9f81bdde4b7292 => {
5577 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5578 let mut req = fidl::new_empty!(BufferCollectionTokenDuplicateRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5579 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenDuplicateRequest>(&header, _body_bytes, handles, &mut req)?;
5580 let control_handle = BufferCollectionTokenControlHandle {
5581 inner: this.inner.clone(),
5582 };
5583 Ok(BufferCollectionTokenRequest::Duplicate {rights_attenuation_mask: req.rights_attenuation_mask,
5584token_request: req.token_request,
5585
5586 control_handle,
5587 })
5588 }
5589 0x76e4ec34fc2cf5b3 => {
5590 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5591 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
5592 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
5593 let control_handle = BufferCollectionTokenControlHandle {
5594 inner: this.inner.clone(),
5595 };
5596 Ok(BufferCollectionTokenRequest::SetDispensable {
5597 control_handle,
5598 })
5599 }
5600 0x2f6243e05f22b9a7 => {
5601 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
5602 let mut req = fidl::new_empty!(BufferCollectionTokenCreateBufferCollectionTokenGroupRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
5603 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(&header, _body_bytes, handles, &mut req)?;
5604 let control_handle = BufferCollectionTokenControlHandle {
5605 inner: this.inner.clone(),
5606 };
5607 Ok(BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {group_request: req.group_request,
5608
5609 control_handle,
5610 })
5611 }
5612 _ => Err(fidl::Error::UnknownOrdinal {
5613 ordinal: header.ordinal,
5614 protocol_name: <BufferCollectionTokenMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
5615 }),
5616 }))
5617 },
5618 )
5619 }
5620}
5621
5622/// A BufferCollectionToken is not a BufferCollection, but rather a way to
5623/// identify a potential shared BufferCollection prior to the BufferCollection
5624/// being allocated.
5625///
5626/// We use a channel for the BufferCollectionToken instead of a single eventpair
5627/// (pair) because this way we can detect error conditions like a participant
5628/// dying mid-create.
5629///
5630/// The fuchsia.sysmem.BufferCollectionToken type is not yet deprecated due to
5631/// its use in some other protocols (for now), but all the internals of
5632/// fuchsia.sysmem.BufferCollectionToken are deprecated. Token channels serve
5633/// both fuchsia.sysmem.BufferCollectionToken and
5634/// fuchsia.sysmem2.BufferCollectionToken.
5635///
5636/// This protocol will be deprecated once other protocols have switched their
5637/// token fields to fuchsia.sysmem2.BufferCollectionToken.
5638#[derive(Debug)]
5639pub enum BufferCollectionTokenRequest {
5640 /// Ensure that previous messages, including Duplicate() messages on a
5641 /// token, collection, or group, have been received server side.
5642 ///
5643 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
5644 /// valid sysmem token risks the Sync() hanging forever. See
5645 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
5646 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
5647 /// Another way is to pass the token to BindSharedCollection(), which also
5648 /// validates the token as part of exchanging it for a BufferCollection
5649 /// channel, and BufferCollection Sync() can then be used.
5650 ///
5651 /// After a Sync(), it's then safe to send the client end of token_request
5652 /// to another participant knowing the server will recognize the token when
5653 /// it's sent into BindSharedCollection() by the other participant.
5654 ///
5655 /// Other options include waiting for each token.Duplicate() to complete
5656 /// individually (using separate call to token.Sync() after each), or
5657 /// calling Sync() on BufferCollection after the token has been turned in
5658 /// via BindSharedCollection().
5659 ///
5660 /// Another way to mitigate is to avoid calling Sync() on the token, and
5661 /// instead later deal with potential failure of BufferCollection.Sync() if
5662 /// the original token was invalid. This option can be preferable from a
5663 /// performance point of view, but requires client code to delay sending
5664 /// tokens duplicated from this token until after client code has converted
5665 /// the duplicating token to a BufferCollection and received successful
5666 /// response from BufferCollection.Sync().
5667 ///
5668 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
5669 /// When BufferCollection.Sync() isn't feasible, the caller must already
5670 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
5671 /// hang forever. See ValidateBufferCollectionToken() to check token
5672 /// validity first if the token isn't already known to be (is/was) valid.
5673 Sync { responder: BufferCollectionTokenSyncResponder },
5674 /// On a BufferCollectionToken channel:
5675 ///
5676 /// Normally a participant will convert a BufferCollectionToken into a
5677 /// BufferCollection view, but a participant is also free to Close() the
5678 /// token (and then close the channel immediately or shortly later in
5679 /// response to server closing its end), which avoids causing logical buffer
5680 /// collection failure. Â Normally an unexpected token channel close will
5681 /// cause logical buffer collection failure (the only exceptions being
5682 /// certain cases involving AttachToken() or SetDispensable()).
5683 ///
5684 /// On a BufferCollection channel:
5685 ///
5686 /// By default the server handles unexpected failure of a BufferCollection
5687 /// by failing the whole logical buffer collection. Partly this is to
5688 /// expedite closing VMO handles to reclaim memory when any participant
5689 /// fails. If a participant would like to cleanly close a BufferCollection
5690 /// view without causing logical buffer collection failure, the participant
5691 /// can send Close() before closing the client end of the BufferCollection
5692 /// channel. If this is the last BufferCollection view, the logical buffer
5693 /// collection will still go away. The Close() can occur before or after
5694 /// SetConstraints(). If before SetConstraints(), the buffer collection
5695 /// won't require constraints from this node in order to allocate. If
5696 /// after SetConstraints(), the constraints are retained and aggregated
5697 /// along with any subsequent logical allocation(s), despite the lack of
5698 /// channel connection.
5699 ///
5700 /// On a BufferCollectionTokenGroup channel:
5701 ///
5702 /// By default, unexpected failure of a BufferCollectionTokenGroup will
5703 /// trigger failure of the logical BufferCollectionTokenGroup and will
5704 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
5705 /// channel without failing the logical group or propagating failure, send
5706 /// Close() before closing the channel client endpoint.
5707 ///
5708 /// If Close() occurs before AllChildrenPresent(), the logical buffer
5709 /// collection will still fail despite the Close() (because sysmem can't be
5710 /// sure whether all relevant children were created, so it's ambiguous
5711 /// whether all relevant constraints will be provided to sysmem). If
5712 /// Close() occurs after AllChildrenPresent(), the children and all their
5713 /// constraints remain intact (just as they would if the
5714 /// BufferCollectionTokenGroup channel had remained open), and the close
5715 /// doesn't trigger or propagate failure.
5716 Close { control_handle: BufferCollectionTokenControlHandle },
5717 /// Set a name for VMOs in this buffer collection. The name may be truncated
5718 /// shorter. The name only affects VMOs allocated after it's set - this call
5719 /// does not rename existing VMOs. If multiple clients set different names
5720 /// then the larger priority value will win.
5721 SetName { priority: u32, name: String, control_handle: BufferCollectionTokenControlHandle },
5722 /// Set information about the current client that can be used by sysmem to
5723 /// help debug leaking memory and hangs waiting for constraints. |name| can
5724 /// be an arbitrary string, but the current process name (see
5725 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
5726 /// arbitrary id, but the current process ID (see
5727 /// fsl::GetCurrentProcessKoid()) is a good default.
5728 ///
5729 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
5730 /// indicate which client is closing their channel first, leading to
5731 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
5732 /// over, but if happening earlier than expected, the
5733 /// client-channel-specific name can help diagnose where the failure is
5734 /// first coming from, from sysmem's point of view).
5735 ///
5736 /// By default (unless overriden by this message or using
5737 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
5738 /// parent Node at the time the child Node is created. While this can be
5739 /// better than nothing, it's often better for each participant to use
5740 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
5741 /// info directly relevant to the current client. Also, SetVerboseLogging()
5742 /// can be used to help disambiguate if a Node is suspected of having info
5743 /// that was copied from its parent.
5744 SetDebugClientInfo { name: String, id: u64, control_handle: BufferCollectionTokenControlHandle },
5745 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
5746 /// after creating a collection. Clients can call this method to change
5747 /// when the log is printed. If multiple client set the deadline, it's
5748 /// unspecified which deadline will take effect.
5749 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: BufferCollectionTokenControlHandle },
5750 /// Verbose logging includes constraints set via SetConstraints() from each
5751 /// client along with info set via SetDebugClientInfo() and the structure of
5752 /// the tree of Node(s).
5753 ///
5754 /// Normally sysmem prints only a single line complaint when aggregation
5755 /// fails, with just the specific detailed reason that aggregation failed,
5756 /// with minimal context. While this is often enough to diagnose a problem
5757 /// if only a small change was made and the system had been working before
5758 /// the small change, it's often not particularly helpful for getting a new
5759 /// buffer collection to work for the first time. Especially with more
5760 /// complex trees of nodes, involving things like AttachToken(),
5761 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
5762 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
5763 /// looks like and why it's failing a logical allocation, or why a tree or
5764 /// sub-tree is failing sooner than expected.
5765 ///
5766 /// The intent of the extra logging is to be acceptable from a performance
5767 /// point of view, if only enabled on a low number of buffer collections.
5768 /// If we're not tracking down a bug, we shouldn't send this message.
5769 ///
5770 /// If too many participants leave verbose logging enabled, we may end up
5771 /// needing to require that system-wide sysmem verbose logging be permitted
5772 /// via some other setting, to avoid sysmem spamming the log too much due to
5773 /// this message.
5774 ///
5775 /// This may be a NOP for some nodes due to intentional policy associated
5776 /// with the node, if we don't trust a node enough to let it turn on verbose
5777 /// logging.
5778 SetVerboseLogging { control_handle: BufferCollectionTokenControlHandle },
5779 /// This gets an event handle that can be used as a parameter to
5780 /// IsAlternateFor() called on any Node. The client will not be granted the
5781 /// right to signal this event, as this handle should only be used as proof
5782 /// that the client obtained this handle from this Node.
5783 ///
5784 /// Because this is a get not a set, no Sync() is needed between the
5785 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
5786 /// potentially being on different channels.
5787 ///
5788 /// See also IsAlternateFor().
5789 GetNodeRef { responder: BufferCollectionTokenGetNodeRefResponder },
5790 /// This checks whether the calling node is in a subtree rooted at a
5791 /// different child token of a common parent BufferCollectionTokenGroup, in
5792 /// relation to the passed-in node_ref.
5793 ///
5794 /// This call is for assisting with admission control de-duplication, and
5795 /// with debugging.
5796 ///
5797 /// The node_ref must be obtained using GetNodeRef() of a
5798 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
5799 ///
5800 /// The node_ref can be a duplicated handle; it's not necessary to call
5801 /// GetNodeRef() for every call to IsAlternateFor().
5802 ///
5803 /// If a calling token may not actually be a valid token at all due to
5804 /// a potentially hostile/untrusted provider of the token, call
5805 /// ValidateBufferCollectionToken() first instead of potentially getting
5806 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
5807 /// token not being a real token (not really talking to sysmem). Another
5808 /// option is to call BindSharedCollection with this token first which also
5809 /// validates the token along with converting it to a BufferCollection, then
5810 /// call BufferCollection IsAlternateFor().
5811 ///
5812 /// error values:
5813 ///
5814 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
5815 /// buffer collection as the calling Node. Before logical allocation and
5816 /// within the same logical allocation sub-tree, this essentially means that
5817 /// the node_ref was never part of this logical buffer collection, since
5818 /// before logical allocation all node_refs that come into existence remain
5819 /// in existence at least until logical allocation (including Node(s) that
5820 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
5821 /// to be returned, this Node's channel needs to still be connected server
5822 /// side, which won't be the case if the whole logical allocation has
5823 /// failed. After logical allocation or in a different logical allocation
5824 /// sub-tree there are additional potential reasons for this error. For
5825 /// example a different logical allocation (separated from this Node(s)
5826 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
5827 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
5828 /// exist and may select a different child sub-tree than the sub-tree the
5829 /// node_ref is in causing deletion of the node_ref Node. The only time
5830 /// sysmem keeps a Node around after that Node has no corresponding channel
5831 /// is when Close() is used and the Node's sub-tree has not yet failed.
5832 /// Another reason for this error is if the node_ref is an eventpair handle
5833 /// with sufficient rights, but isn't actually a real node_ref obtained from
5834 /// GetNodeRef().
5835 ///
5836 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
5837 /// eventpair handle, or doesn't have the needed rights expected on a real
5838 /// node_ref.
5839 ///
5840 /// No other failing status codes are returned by this call. However,
5841 /// sysmem may add additional codes in future, so the client should have
5842 /// sensible default handling for any failing status code.
5843 ///
5844 /// On success, is_alternate has the following meaning:
5845 /// * true - The first parent node in common between the calling node and
5846 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
5847 /// the calling Node and the node_ref Node will _not_ have both their
5848 /// constraints apply - rather sysmem will choose one or the other of
5849 /// the constraints - never both. This is because only one child of
5850 /// a BufferCollectionTokenGroup is selected during logical allocation,
5851 /// with only that one child's sub-tree contributing to constraints
5852 /// aggregation.
5853 /// * false - The first parent node in common between the calling Node and
5854 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
5855 /// this means the first parent node in common is a
5856 /// BufferCollectionToken or BufferCollection (regardless of not
5857 /// Close()ed or Close()ed). This means that the calling Node and the
5858 /// node_ref Node _may_ have both their constraints apply during
5859 /// constraints aggregation of the logical allocation, if both Node(s)
5860 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
5861 /// In this case, there is no BufferCollectionTokenGroup that will
5862 /// directly prevent the two Node(s) from both being selected and their
5863 /// constraints both aggregated, but even when false, one or both
5864 /// Node(s) may still be eliminated from consideration if one or both
5865 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
5866 /// which selects a child sub-tree other than the sub-tree containing
5867 /// the calling Node or node_ref Node.
5868 IsAlternateFor {
5869 node_ref: fidl::Event,
5870 responder: BufferCollectionTokenIsAlternateForResponder,
5871 },
5872 /// This method can be used to add more participants prior to creating a
5873 /// shared BufferCollection. A new token will be returned for each entry in
5874 /// the `rights_attenuation_masks` array. The return value is the client
5875 /// ends of each new participant token.
5876 ///
5877 /// If the calling token may not actually be a valid token at all due to
5878 /// a potentially hostile/untrusted provider of the token, consider using
5879 /// ValidateBufferCollectionToken() first instead of potentially getting
5880 /// stuck indefinitely if DuplicateSync() never responds due to the calling
5881 /// token not being a real token.
5882 ///
5883 /// In contrast to Duplicate(), no Sync() (see "protocol Node") is needed
5884 /// after calling this method.
5885 ///
5886 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5887 /// BufferCollection to be successfully created.
5888 ///
5889 /// In each entry of `rights_attenuation_masks`, rights bits that are zero
5890 /// will be absent in the buffer VMO rights obtainable via the corresponding
5891 /// returned token. This allows an initiator or intermediary participant to
5892 /// attenuate the rights available to a participant. This does not allow a
5893 /// participant to gain rights that the participant doesn't already have.
5894 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5895 /// attenuation should be applied.
5896 DuplicateSync {
5897 rights_attenuation_masks: Vec<fidl::Rights>,
5898 responder: BufferCollectionTokenDuplicateSyncResponder,
5899 },
5900 /// This method can be used to add a participant prior to creating a shared
5901 /// BufferCollection. It should only be used instead of DuplicateSync in
5902 /// performance sensitive cases where it would be undesireable to wait for
5903 /// sysmem to respond as part of each duplicate.
5904 ///
5905 /// After sending one or more Duplicate() messages, and before sending the
5906 /// created tokens to other participants (or to other Allocator channels),
5907 /// the client should send a Sync() and wait for its response. The Sync()
5908 /// call can be made on the token, or on the BufferCollection obtained by
5909 /// passing this token to BindSharedCollection(). Either will ensure that
5910 /// the server knows about the tokens created via Duplicate() before the
5911 /// other participant sends the token to the server via separate Allocator
5912 /// channel.
5913 ///
5914 /// All tokens must be turned in via BindSharedCollection() or Close() for a
5915 /// BufferCollection to be successfully created.
5916 ///
5917 /// When a client calls BindSharedCollection() to turn in a
5918 /// BufferCollectionToken, the server will process all Duplicate() messages
5919 /// before closing down the BufferCollectionToken. This allows the client
5920 /// to Duplicate() and immediately turn in the BufferCollectionToken using
5921 /// BindSharedCollection, then later transfer the client end of token_request
5922 /// to another participant - the server will notice the existence of the
5923 /// token_request before considering this BufferCollectionToken fully closed.
5924 ///
5925 /// `rights_attenuation_mask` rights bits that are zero in this mask will be
5926 /// absent in the buffer VMO rights obtainable via the client end of
5927 /// token_request. This allows an initiator or intermediary participant to
5928 /// attenuate the rights available to a participant. This does not allow a
5929 /// participant to gain rights that the participant doesn't already have.
5930 /// The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no
5931 /// attenuation should be applied.
5932 ///
5933 /// These values for rights_attenuation_mask result in no attenuation:
5934 /// * ZX_RIGHT_SAME_RIGHTS (preferred)
5935 /// * 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
5936 /// * 0 (deprecated - do not use 0 - an ERROR will go to the log)
5937 ///
5938 /// `token_request` is the server end of a BufferCollectionToken channel.
5939 /// The client end of this channel acts as another participant in creating the
5940 /// shared BufferCollection.
5941 Duplicate {
5942 rights_attenuation_mask: u32,
5943 token_request: fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
5944 control_handle: BufferCollectionTokenControlHandle,
5945 },
5946 /// A dispensable token can fail after buffers are logically allocated
5947 /// without causing failure of its parent (if any).
5948 ///
5949 /// The dispensable token participates in constraints aggregation along with
5950 /// its parent before logical buffer allocation. If the dispensable token
5951 /// fails before buffers are logically allocated, the failure propagates to
5952 /// the dispensable token's parent.
5953 ///
5954 /// After buffers are logically allocated, failure of the dispensable token
5955 /// (or any child of the dispensable token) does not propagate to the
5956 /// dispensable token's parent. Failure does propagate from a normal
5957 /// child of a dispensable token to the dispensable token. Failure
5958 /// of a child is blocked from reaching its parent if the child is attached,
5959 /// or if the child is dispensable and the failure occurred after logical
5960 /// allocation.
5961 ///
5962 /// A dispensable token can be used in cases where a participant needs to
5963 /// provide constraints, but after buffers are allocated, the participant
5964 /// can fail without causing buffer collection failure from the parent's
5965 /// point of view.
5966 ///
5967 /// In contrast, AttachToken() can be used to create a token which does not
5968 /// participate in constraints aggregation with its parent, and whose
5969 /// failure at any time does not propagate to its parent, and whose delay
5970 /// providing constraints does not prevent the parent from completing its
5971 /// buffer allocation.
5972 ///
5973 /// An initiator may in some scenarios choose to initially use a dispensable
5974 /// token for a given instance of a participant, and then later if the first
5975 /// instance of that participant fails, a new second instance of that
5976 /// participant my be given a token created with AttachToken().
5977 ///
5978 /// If a client uses this message, the client should not rely on the
5979 /// client's own BufferCollectionToken or BufferCollection channel to close
5980 /// from the server end due to abrupt failure of any BufferCollectionToken
5981 /// or BufferCollection that the client has SetDispensable() and given out
5982 /// to another process. For this reason, the client should take extra care
5983 /// to notice failure of that other process via other means.
5984 ///
5985 /// While it is possible (and potentially useful) to SetDispensable() on a
5986 /// direct child of a BufferCollectionTokenGroup, it isn't possible to later
5987 /// replace a failed dispensable token that was a direct child of a group
5988 /// with a new token using AttachToken() (since there's no AttachToken() on
5989 /// a group). Instead, to enable AttachToken() replacement in this case,
5990 /// create an additional non-dispensable token (node) that's a direct child
5991 /// of the group and make the existing dispensable token a child of the
5992 /// additional token (node). This way, the additional token (node) that is
5993 /// a direct child of the group has BufferCollection.AttachToken() which can
5994 /// be used to replace the failed dispensable token.
5995 ///
5996 /// SetDispensable() on an already-dispensable token is idempotent.
5997 SetDispensable { control_handle: BufferCollectionTokenControlHandle },
5998 /// Most sysmem clients and many participants don't need to care about this
5999 /// message or about BufferCollectionTokenGroup(s) in general.
6000 ///
6001 /// A BufferCollectionTokenGroup is used to create a 1 of N OR among N child
6002 /// tokens. The child tokens which are not selected during aggregation will
6003 /// fail (close), which a potential participant should notice when their
6004 /// BufferCollection channel client endpoint sees PEER_CLOSED, allowing the
6005 /// participant to clean up the speculative usage that didn't end up
6006 /// happening (similarly to a normal BufferCollection server end closing
6007 /// on failure of a logical buffer collection).
6008 ///
6009 /// See comments on protocol BufferCollectionTokenGroup.
6010 ///
6011 /// Any rights_attenuation_mask or AttachToken()/SetDispensable() to be
6012 /// applied to the whole group can be achieved with a token for this purpose
6013 /// as a direct parent of the group.
6014 ///
6015 /// group_request - the server end of a BufferCollectionTokenGroup channel
6016 /// to be served by sysmem.
6017 CreateBufferCollectionTokenGroup {
6018 group_request: fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
6019 control_handle: BufferCollectionTokenControlHandle,
6020 },
6021}
6022
6023impl BufferCollectionTokenRequest {
6024 #[allow(irrefutable_let_patterns)]
6025 pub fn into_sync(self) -> Option<(BufferCollectionTokenSyncResponder)> {
6026 if let BufferCollectionTokenRequest::Sync { responder } = self {
6027 Some((responder))
6028 } else {
6029 None
6030 }
6031 }
6032
6033 #[allow(irrefutable_let_patterns)]
6034 pub fn into_close(self) -> Option<(BufferCollectionTokenControlHandle)> {
6035 if let BufferCollectionTokenRequest::Close { control_handle } = self {
6036 Some((control_handle))
6037 } else {
6038 None
6039 }
6040 }
6041
6042 #[allow(irrefutable_let_patterns)]
6043 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionTokenControlHandle)> {
6044 if let BufferCollectionTokenRequest::SetName { priority, name, control_handle } = self {
6045 Some((priority, name, control_handle))
6046 } else {
6047 None
6048 }
6049 }
6050
6051 #[allow(irrefutable_let_patterns)]
6052 pub fn into_set_debug_client_info(
6053 self,
6054 ) -> Option<(String, u64, BufferCollectionTokenControlHandle)> {
6055 if let BufferCollectionTokenRequest::SetDebugClientInfo { name, id, control_handle } = self
6056 {
6057 Some((name, id, control_handle))
6058 } else {
6059 None
6060 }
6061 }
6062
6063 #[allow(irrefutable_let_patterns)]
6064 pub fn into_set_debug_timeout_log_deadline(
6065 self,
6066 ) -> Option<(i64, BufferCollectionTokenControlHandle)> {
6067 if let BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline {
6068 deadline,
6069 control_handle,
6070 } = self
6071 {
6072 Some((deadline, control_handle))
6073 } else {
6074 None
6075 }
6076 }
6077
6078 #[allow(irrefutable_let_patterns)]
6079 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenControlHandle)> {
6080 if let BufferCollectionTokenRequest::SetVerboseLogging { control_handle } = self {
6081 Some((control_handle))
6082 } else {
6083 None
6084 }
6085 }
6086
6087 #[allow(irrefutable_let_patterns)]
6088 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGetNodeRefResponder)> {
6089 if let BufferCollectionTokenRequest::GetNodeRef { responder } = self {
6090 Some((responder))
6091 } else {
6092 None
6093 }
6094 }
6095
6096 #[allow(irrefutable_let_patterns)]
6097 pub fn into_is_alternate_for(
6098 self,
6099 ) -> Option<(fidl::Event, BufferCollectionTokenIsAlternateForResponder)> {
6100 if let BufferCollectionTokenRequest::IsAlternateFor { node_ref, responder } = self {
6101 Some((node_ref, responder))
6102 } else {
6103 None
6104 }
6105 }
6106
6107 #[allow(irrefutable_let_patterns)]
6108 pub fn into_duplicate_sync(
6109 self,
6110 ) -> Option<(Vec<fidl::Rights>, BufferCollectionTokenDuplicateSyncResponder)> {
6111 if let BufferCollectionTokenRequest::DuplicateSync { rights_attenuation_masks, responder } =
6112 self
6113 {
6114 Some((rights_attenuation_masks, responder))
6115 } else {
6116 None
6117 }
6118 }
6119
6120 #[allow(irrefutable_let_patterns)]
6121 pub fn into_duplicate(
6122 self,
6123 ) -> Option<(
6124 u32,
6125 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
6126 BufferCollectionTokenControlHandle,
6127 )> {
6128 if let BufferCollectionTokenRequest::Duplicate {
6129 rights_attenuation_mask,
6130 token_request,
6131 control_handle,
6132 } = self
6133 {
6134 Some((rights_attenuation_mask, token_request, control_handle))
6135 } else {
6136 None
6137 }
6138 }
6139
6140 #[allow(irrefutable_let_patterns)]
6141 pub fn into_set_dispensable(self) -> Option<(BufferCollectionTokenControlHandle)> {
6142 if let BufferCollectionTokenRequest::SetDispensable { control_handle } = self {
6143 Some((control_handle))
6144 } else {
6145 None
6146 }
6147 }
6148
6149 #[allow(irrefutable_let_patterns)]
6150 pub fn into_create_buffer_collection_token_group(
6151 self,
6152 ) -> Option<(
6153 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
6154 BufferCollectionTokenControlHandle,
6155 )> {
6156 if let BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup {
6157 group_request,
6158 control_handle,
6159 } = self
6160 {
6161 Some((group_request, control_handle))
6162 } else {
6163 None
6164 }
6165 }
6166
6167 /// Name of the method defined in FIDL
6168 pub fn method_name(&self) -> &'static str {
6169 match *self {
6170 BufferCollectionTokenRequest::Sync { .. } => "sync",
6171 BufferCollectionTokenRequest::Close { .. } => "close",
6172 BufferCollectionTokenRequest::SetName { .. } => "set_name",
6173 BufferCollectionTokenRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
6174 BufferCollectionTokenRequest::SetDebugTimeoutLogDeadline { .. } => {
6175 "set_debug_timeout_log_deadline"
6176 }
6177 BufferCollectionTokenRequest::SetVerboseLogging { .. } => "set_verbose_logging",
6178 BufferCollectionTokenRequest::GetNodeRef { .. } => "get_node_ref",
6179 BufferCollectionTokenRequest::IsAlternateFor { .. } => "is_alternate_for",
6180 BufferCollectionTokenRequest::DuplicateSync { .. } => "duplicate_sync",
6181 BufferCollectionTokenRequest::Duplicate { .. } => "duplicate",
6182 BufferCollectionTokenRequest::SetDispensable { .. } => "set_dispensable",
6183 BufferCollectionTokenRequest::CreateBufferCollectionTokenGroup { .. } => {
6184 "create_buffer_collection_token_group"
6185 }
6186 }
6187 }
6188}
6189
6190#[derive(Debug, Clone)]
6191pub struct BufferCollectionTokenControlHandle {
6192 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
6193}
6194
6195impl BufferCollectionTokenControlHandle {
6196 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
6197 self.inner.shutdown_with_epitaph(status.into())
6198 }
6199}
6200
6201impl fidl::endpoints::ControlHandle for BufferCollectionTokenControlHandle {
6202 fn shutdown(&self) {
6203 self.inner.shutdown()
6204 }
6205
6206 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
6207 self.inner.shutdown_with_epitaph(status)
6208 }
6209
6210 fn is_closed(&self) -> bool {
6211 self.inner.channel().is_closed()
6212 }
6213 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
6214 self.inner.channel().on_closed()
6215 }
6216
6217 #[cfg(target_os = "fuchsia")]
6218 fn signal_peer(
6219 &self,
6220 clear_mask: zx::Signals,
6221 set_mask: zx::Signals,
6222 ) -> Result<(), zx_status::Status> {
6223 use fidl::Peered;
6224 self.inner.channel().signal_peer(clear_mask, set_mask)
6225 }
6226}
6227
6228impl BufferCollectionTokenControlHandle {}
6229
6230#[must_use = "FIDL methods require a response to be sent"]
6231#[derive(Debug)]
6232pub struct BufferCollectionTokenSyncResponder {
6233 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6234 tx_id: u32,
6235}
6236
6237/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6238/// if the responder is dropped without sending a response, so that the client
6239/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6240impl std::ops::Drop for BufferCollectionTokenSyncResponder {
6241 fn drop(&mut self) {
6242 self.control_handle.shutdown();
6243 // Safety: drops once, never accessed again
6244 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6245 }
6246}
6247
6248impl fidl::endpoints::Responder for BufferCollectionTokenSyncResponder {
6249 type ControlHandle = BufferCollectionTokenControlHandle;
6250
6251 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6252 &self.control_handle
6253 }
6254
6255 fn drop_without_shutdown(mut self) {
6256 // Safety: drops once, never accessed again due to mem::forget
6257 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6258 // Prevent Drop from running (which would shut down the channel)
6259 std::mem::forget(self);
6260 }
6261}
6262
6263impl BufferCollectionTokenSyncResponder {
6264 /// Sends a response to the FIDL transaction.
6265 ///
6266 /// Sets the channel to shutdown if an error occurs.
6267 pub fn send(self) -> Result<(), fidl::Error> {
6268 let _result = self.send_raw();
6269 if _result.is_err() {
6270 self.control_handle.shutdown();
6271 }
6272 self.drop_without_shutdown();
6273 _result
6274 }
6275
6276 /// Similar to "send" but does not shutdown the channel if an error occurs.
6277 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
6278 let _result = self.send_raw();
6279 self.drop_without_shutdown();
6280 _result
6281 }
6282
6283 fn send_raw(&self) -> Result<(), fidl::Error> {
6284 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
6285 (),
6286 self.tx_id,
6287 0x4577e238ae26291,
6288 fidl::encoding::DynamicFlags::empty(),
6289 )
6290 }
6291}
6292
6293#[must_use = "FIDL methods require a response to be sent"]
6294#[derive(Debug)]
6295pub struct BufferCollectionTokenGetNodeRefResponder {
6296 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6297 tx_id: u32,
6298}
6299
6300/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6301/// if the responder is dropped without sending a response, so that the client
6302/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6303impl std::ops::Drop for BufferCollectionTokenGetNodeRefResponder {
6304 fn drop(&mut self) {
6305 self.control_handle.shutdown();
6306 // Safety: drops once, never accessed again
6307 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6308 }
6309}
6310
6311impl fidl::endpoints::Responder for BufferCollectionTokenGetNodeRefResponder {
6312 type ControlHandle = BufferCollectionTokenControlHandle;
6313
6314 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6315 &self.control_handle
6316 }
6317
6318 fn drop_without_shutdown(mut self) {
6319 // Safety: drops once, never accessed again due to mem::forget
6320 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6321 // Prevent Drop from running (which would shut down the channel)
6322 std::mem::forget(self);
6323 }
6324}
6325
6326impl BufferCollectionTokenGetNodeRefResponder {
6327 /// Sends a response to the FIDL transaction.
6328 ///
6329 /// Sets the channel to shutdown if an error occurs.
6330 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6331 let _result = self.send_raw(node_ref);
6332 if _result.is_err() {
6333 self.control_handle.shutdown();
6334 }
6335 self.drop_without_shutdown();
6336 _result
6337 }
6338
6339 /// Similar to "send" but does not shutdown the channel if an error occurs.
6340 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6341 let _result = self.send_raw(node_ref);
6342 self.drop_without_shutdown();
6343 _result
6344 }
6345
6346 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
6347 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
6348 (node_ref,),
6349 self.tx_id,
6350 0x467b7c75c35c3b84,
6351 fidl::encoding::DynamicFlags::empty(),
6352 )
6353 }
6354}
6355
6356#[must_use = "FIDL methods require a response to be sent"]
6357#[derive(Debug)]
6358pub struct BufferCollectionTokenIsAlternateForResponder {
6359 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6360 tx_id: u32,
6361}
6362
6363/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6364/// if the responder is dropped without sending a response, so that the client
6365/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6366impl std::ops::Drop for BufferCollectionTokenIsAlternateForResponder {
6367 fn drop(&mut self) {
6368 self.control_handle.shutdown();
6369 // Safety: drops once, never accessed again
6370 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6371 }
6372}
6373
6374impl fidl::endpoints::Responder for BufferCollectionTokenIsAlternateForResponder {
6375 type ControlHandle = BufferCollectionTokenControlHandle;
6376
6377 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6378 &self.control_handle
6379 }
6380
6381 fn drop_without_shutdown(mut self) {
6382 // Safety: drops once, never accessed again due to mem::forget
6383 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6384 // Prevent Drop from running (which would shut down the channel)
6385 std::mem::forget(self);
6386 }
6387}
6388
6389impl BufferCollectionTokenIsAlternateForResponder {
6390 /// Sends a response to the FIDL transaction.
6391 ///
6392 /// Sets the channel to shutdown if an error occurs.
6393 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6394 let _result = self.send_raw(result);
6395 if _result.is_err() {
6396 self.control_handle.shutdown();
6397 }
6398 self.drop_without_shutdown();
6399 _result
6400 }
6401
6402 /// Similar to "send" but does not shutdown the channel if an error occurs.
6403 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6404 let _result = self.send_raw(result);
6405 self.drop_without_shutdown();
6406 _result
6407 }
6408
6409 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
6410 self.control_handle
6411 .inner
6412 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
6413 result.map(|is_alternate| (is_alternate,)),
6414 self.tx_id,
6415 0x33a2a7aff2776c07,
6416 fidl::encoding::DynamicFlags::empty(),
6417 )
6418 }
6419}
6420
6421#[must_use = "FIDL methods require a response to be sent"]
6422#[derive(Debug)]
6423pub struct BufferCollectionTokenDuplicateSyncResponder {
6424 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenControlHandle>,
6425 tx_id: u32,
6426}
6427
6428/// Set the the channel to be shutdown (see [`BufferCollectionTokenControlHandle::shutdown`])
6429/// if the responder is dropped without sending a response, so that the client
6430/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
6431impl std::ops::Drop for BufferCollectionTokenDuplicateSyncResponder {
6432 fn drop(&mut self) {
6433 self.control_handle.shutdown();
6434 // Safety: drops once, never accessed again
6435 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6436 }
6437}
6438
6439impl fidl::endpoints::Responder for BufferCollectionTokenDuplicateSyncResponder {
6440 type ControlHandle = BufferCollectionTokenControlHandle;
6441
6442 fn control_handle(&self) -> &BufferCollectionTokenControlHandle {
6443 &self.control_handle
6444 }
6445
6446 fn drop_without_shutdown(mut self) {
6447 // Safety: drops once, never accessed again due to mem::forget
6448 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
6449 // Prevent Drop from running (which would shut down the channel)
6450 std::mem::forget(self);
6451 }
6452}
6453
6454impl BufferCollectionTokenDuplicateSyncResponder {
6455 /// Sends a response to the FIDL transaction.
6456 ///
6457 /// Sets the channel to shutdown if an error occurs.
6458 pub fn send(
6459 self,
6460 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6461 ) -> Result<(), fidl::Error> {
6462 let _result = self.send_raw(tokens);
6463 if _result.is_err() {
6464 self.control_handle.shutdown();
6465 }
6466 self.drop_without_shutdown();
6467 _result
6468 }
6469
6470 /// Similar to "send" but does not shutdown the channel if an error occurs.
6471 pub fn send_no_shutdown_on_err(
6472 self,
6473 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6474 ) -> Result<(), fidl::Error> {
6475 let _result = self.send_raw(tokens);
6476 self.drop_without_shutdown();
6477 _result
6478 }
6479
6480 fn send_raw(
6481 &self,
6482 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6483 ) -> Result<(), fidl::Error> {
6484 self.control_handle.inner.send::<BufferCollectionTokenDuplicateSyncResponse>(
6485 (tokens.as_mut(),),
6486 self.tx_id,
6487 0x49ed7ab7cc19f18,
6488 fidl::encoding::DynamicFlags::empty(),
6489 )
6490 }
6491}
6492
6493#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
6494pub struct BufferCollectionTokenGroupMarker;
6495
6496impl fidl::endpoints::ProtocolMarker for BufferCollectionTokenGroupMarker {
6497 type Proxy = BufferCollectionTokenGroupProxy;
6498 type RequestStream = BufferCollectionTokenGroupRequestStream;
6499 #[cfg(target_os = "fuchsia")]
6500 type SynchronousProxy = BufferCollectionTokenGroupSynchronousProxy;
6501
6502 const DEBUG_NAME: &'static str = "(anonymous) BufferCollectionTokenGroup";
6503}
6504
6505pub trait BufferCollectionTokenGroupProxyInterface: Send + Sync {
6506 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
6507 fn r#sync(&self) -> Self::SyncResponseFut;
6508 fn r#close(&self) -> Result<(), fidl::Error>;
6509 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
6510 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
6511 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
6512 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
6513 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
6514 + Send;
6515 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
6516 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
6517 + Send;
6518 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
6519 fn r#create_child(
6520 &self,
6521 payload: BufferCollectionTokenGroupCreateChildRequest,
6522 ) -> Result<(), fidl::Error>;
6523 type CreateChildrenSyncResponseFut: std::future::Future<
6524 Output = Result<
6525 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
6526 fidl::Error,
6527 >,
6528 > + Send;
6529 fn r#create_children_sync(
6530 &self,
6531 rights_attenuation_masks: &[fidl::Rights],
6532 ) -> Self::CreateChildrenSyncResponseFut;
6533 fn r#all_children_present(&self) -> Result<(), fidl::Error>;
6534}
6535#[derive(Debug)]
6536#[cfg(target_os = "fuchsia")]
6537pub struct BufferCollectionTokenGroupSynchronousProxy {
6538 client: fidl::client::sync::Client,
6539}
6540
6541#[cfg(target_os = "fuchsia")]
6542impl fidl::endpoints::SynchronousProxy for BufferCollectionTokenGroupSynchronousProxy {
6543 type Proxy = BufferCollectionTokenGroupProxy;
6544 type Protocol = BufferCollectionTokenGroupMarker;
6545
6546 fn from_channel(inner: fidl::Channel) -> Self {
6547 Self::new(inner)
6548 }
6549
6550 fn into_channel(self) -> fidl::Channel {
6551 self.client.into_channel()
6552 }
6553
6554 fn as_channel(&self) -> &fidl::Channel {
6555 self.client.as_channel()
6556 }
6557}
6558
6559#[cfg(target_os = "fuchsia")]
6560impl BufferCollectionTokenGroupSynchronousProxy {
6561 pub fn new(channel: fidl::Channel) -> Self {
6562 Self { client: fidl::client::sync::Client::new(channel) }
6563 }
6564
6565 pub fn into_channel(self) -> fidl::Channel {
6566 self.client.into_channel()
6567 }
6568
6569 /// Waits until an event arrives and returns it. It is safe for other
6570 /// threads to make concurrent requests while waiting for an event.
6571 pub fn wait_for_event(
6572 &self,
6573 deadline: zx::MonotonicInstant,
6574 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
6575 BufferCollectionTokenGroupEvent::decode(
6576 self.client.wait_for_event::<BufferCollectionTokenGroupMarker>(deadline)?,
6577 )
6578 }
6579
6580 /// Ensure that previous messages, including Duplicate() messages on a
6581 /// token, collection, or group, have been received server side.
6582 ///
6583 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
6584 /// valid sysmem token risks the Sync() hanging forever. See
6585 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
6586 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
6587 /// Another way is to pass the token to BindSharedCollection(), which also
6588 /// validates the token as part of exchanging it for a BufferCollection
6589 /// channel, and BufferCollection Sync() can then be used.
6590 ///
6591 /// After a Sync(), it's then safe to send the client end of token_request
6592 /// to another participant knowing the server will recognize the token when
6593 /// it's sent into BindSharedCollection() by the other participant.
6594 ///
6595 /// Other options include waiting for each token.Duplicate() to complete
6596 /// individually (using separate call to token.Sync() after each), or
6597 /// calling Sync() on BufferCollection after the token has been turned in
6598 /// via BindSharedCollection().
6599 ///
6600 /// Another way to mitigate is to avoid calling Sync() on the token, and
6601 /// instead later deal with potential failure of BufferCollection.Sync() if
6602 /// the original token was invalid. This option can be preferable from a
6603 /// performance point of view, but requires client code to delay sending
6604 /// tokens duplicated from this token until after client code has converted
6605 /// the duplicating token to a BufferCollection and received successful
6606 /// response from BufferCollection.Sync().
6607 ///
6608 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
6609 /// When BufferCollection.Sync() isn't feasible, the caller must already
6610 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
6611 /// hang forever. See ValidateBufferCollectionToken() to check token
6612 /// validity first if the token isn't already known to be (is/was) valid.
6613 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
6614 let _response = self.client.send_query::<
6615 fidl::encoding::EmptyPayload,
6616 fidl::encoding::EmptyPayload,
6617 BufferCollectionTokenGroupMarker,
6618 >(
6619 (),
6620 0x4577e238ae26291,
6621 fidl::encoding::DynamicFlags::empty(),
6622 ___deadline,
6623 )?;
6624 Ok(_response)
6625 }
6626
6627 /// On a BufferCollectionToken channel:
6628 ///
6629 /// Normally a participant will convert a BufferCollectionToken into a
6630 /// BufferCollection view, but a participant is also free to Close() the
6631 /// token (and then close the channel immediately or shortly later in
6632 /// response to server closing its end), which avoids causing logical buffer
6633 /// collection failure. Â Normally an unexpected token channel close will
6634 /// cause logical buffer collection failure (the only exceptions being
6635 /// certain cases involving AttachToken() or SetDispensable()).
6636 ///
6637 /// On a BufferCollection channel:
6638 ///
6639 /// By default the server handles unexpected failure of a BufferCollection
6640 /// by failing the whole logical buffer collection. Partly this is to
6641 /// expedite closing VMO handles to reclaim memory when any participant
6642 /// fails. If a participant would like to cleanly close a BufferCollection
6643 /// view without causing logical buffer collection failure, the participant
6644 /// can send Close() before closing the client end of the BufferCollection
6645 /// channel. If this is the last BufferCollection view, the logical buffer
6646 /// collection will still go away. The Close() can occur before or after
6647 /// SetConstraints(). If before SetConstraints(), the buffer collection
6648 /// won't require constraints from this node in order to allocate. If
6649 /// after SetConstraints(), the constraints are retained and aggregated
6650 /// along with any subsequent logical allocation(s), despite the lack of
6651 /// channel connection.
6652 ///
6653 /// On a BufferCollectionTokenGroup channel:
6654 ///
6655 /// By default, unexpected failure of a BufferCollectionTokenGroup will
6656 /// trigger failure of the logical BufferCollectionTokenGroup and will
6657 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
6658 /// channel without failing the logical group or propagating failure, send
6659 /// Close() before closing the channel client endpoint.
6660 ///
6661 /// If Close() occurs before AllChildrenPresent(), the logical buffer
6662 /// collection will still fail despite the Close() (because sysmem can't be
6663 /// sure whether all relevant children were created, so it's ambiguous
6664 /// whether all relevant constraints will be provided to sysmem). If
6665 /// Close() occurs after AllChildrenPresent(), the children and all their
6666 /// constraints remain intact (just as they would if the
6667 /// BufferCollectionTokenGroup channel had remained open), and the close
6668 /// doesn't trigger or propagate failure.
6669 pub fn r#close(&self) -> Result<(), fidl::Error> {
6670 self.client.send::<fidl::encoding::EmptyPayload>(
6671 (),
6672 0x5b1d7a4f5681fca7,
6673 fidl::encoding::DynamicFlags::empty(),
6674 )
6675 }
6676
6677 /// Set a name for VMOs in this buffer collection. The name may be truncated
6678 /// shorter. The name only affects VMOs allocated after it's set - this call
6679 /// does not rename existing VMOs. If multiple clients set different names
6680 /// then the larger priority value will win.
6681 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
6682 self.client.send::<NodeSetNameRequest>(
6683 (priority, name),
6684 0x77a41bb6217e2443,
6685 fidl::encoding::DynamicFlags::empty(),
6686 )
6687 }
6688
6689 /// Set information about the current client that can be used by sysmem to
6690 /// help debug leaking memory and hangs waiting for constraints. |name| can
6691 /// be an arbitrary string, but the current process name (see
6692 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
6693 /// arbitrary id, but the current process ID (see
6694 /// fsl::GetCurrentProcessKoid()) is a good default.
6695 ///
6696 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
6697 /// indicate which client is closing their channel first, leading to
6698 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
6699 /// over, but if happening earlier than expected, the
6700 /// client-channel-specific name can help diagnose where the failure is
6701 /// first coming from, from sysmem's point of view).
6702 ///
6703 /// By default (unless overriden by this message or using
6704 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
6705 /// parent Node at the time the child Node is created. While this can be
6706 /// better than nothing, it's often better for each participant to use
6707 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
6708 /// info directly relevant to the current client. Also, SetVerboseLogging()
6709 /// can be used to help disambiguate if a Node is suspected of having info
6710 /// that was copied from its parent.
6711 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
6712 self.client.send::<NodeSetDebugClientInfoRequest>(
6713 (name, id),
6714 0x7275759070eb5ee2,
6715 fidl::encoding::DynamicFlags::empty(),
6716 )
6717 }
6718
6719 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
6720 /// after creating a collection. Clients can call this method to change
6721 /// when the log is printed. If multiple client set the deadline, it's
6722 /// unspecified which deadline will take effect.
6723 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
6724 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
6725 (deadline,),
6726 0x46d38f4772638867,
6727 fidl::encoding::DynamicFlags::empty(),
6728 )
6729 }
6730
6731 /// Verbose logging includes constraints set via SetConstraints() from each
6732 /// client along with info set via SetDebugClientInfo() and the structure of
6733 /// the tree of Node(s).
6734 ///
6735 /// Normally sysmem prints only a single line complaint when aggregation
6736 /// fails, with just the specific detailed reason that aggregation failed,
6737 /// with minimal context. While this is often enough to diagnose a problem
6738 /// if only a small change was made and the system had been working before
6739 /// the small change, it's often not particularly helpful for getting a new
6740 /// buffer collection to work for the first time. Especially with more
6741 /// complex trees of nodes, involving things like AttachToken(),
6742 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
6743 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
6744 /// looks like and why it's failing a logical allocation, or why a tree or
6745 /// sub-tree is failing sooner than expected.
6746 ///
6747 /// The intent of the extra logging is to be acceptable from a performance
6748 /// point of view, if only enabled on a low number of buffer collections.
6749 /// If we're not tracking down a bug, we shouldn't send this message.
6750 ///
6751 /// If too many participants leave verbose logging enabled, we may end up
6752 /// needing to require that system-wide sysmem verbose logging be permitted
6753 /// via some other setting, to avoid sysmem spamming the log too much due to
6754 /// this message.
6755 ///
6756 /// This may be a NOP for some nodes due to intentional policy associated
6757 /// with the node, if we don't trust a node enough to let it turn on verbose
6758 /// logging.
6759 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
6760 self.client.send::<fidl::encoding::EmptyPayload>(
6761 (),
6762 0x6bfbe2cf1701d288,
6763 fidl::encoding::DynamicFlags::empty(),
6764 )
6765 }
6766
6767 /// This gets an event handle that can be used as a parameter to
6768 /// IsAlternateFor() called on any Node. The client will not be granted the
6769 /// right to signal this event, as this handle should only be used as proof
6770 /// that the client obtained this handle from this Node.
6771 ///
6772 /// Because this is a get not a set, no Sync() is needed between the
6773 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
6774 /// potentially being on different channels.
6775 ///
6776 /// See also IsAlternateFor().
6777 pub fn r#get_node_ref(
6778 &self,
6779 ___deadline: zx::MonotonicInstant,
6780 ) -> Result<fidl::Event, fidl::Error> {
6781 let _response = self.client.send_query::<
6782 fidl::encoding::EmptyPayload,
6783 NodeGetNodeRefResponse,
6784 BufferCollectionTokenGroupMarker,
6785 >(
6786 (),
6787 0x467b7c75c35c3b84,
6788 fidl::encoding::DynamicFlags::empty(),
6789 ___deadline,
6790 )?;
6791 Ok(_response.node_ref)
6792 }
6793
6794 /// This checks whether the calling node is in a subtree rooted at a
6795 /// different child token of a common parent BufferCollectionTokenGroup, in
6796 /// relation to the passed-in node_ref.
6797 ///
6798 /// This call is for assisting with admission control de-duplication, and
6799 /// with debugging.
6800 ///
6801 /// The node_ref must be obtained using GetNodeRef() of a
6802 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
6803 ///
6804 /// The node_ref can be a duplicated handle; it's not necessary to call
6805 /// GetNodeRef() for every call to IsAlternateFor().
6806 ///
6807 /// If a calling token may not actually be a valid token at all due to
6808 /// a potentially hostile/untrusted provider of the token, call
6809 /// ValidateBufferCollectionToken() first instead of potentially getting
6810 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
6811 /// token not being a real token (not really talking to sysmem). Another
6812 /// option is to call BindSharedCollection with this token first which also
6813 /// validates the token along with converting it to a BufferCollection, then
6814 /// call BufferCollection IsAlternateFor().
6815 ///
6816 /// error values:
6817 ///
6818 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
6819 /// buffer collection as the calling Node. Before logical allocation and
6820 /// within the same logical allocation sub-tree, this essentially means that
6821 /// the node_ref was never part of this logical buffer collection, since
6822 /// before logical allocation all node_refs that come into existence remain
6823 /// in existence at least until logical allocation (including Node(s) that
6824 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
6825 /// to be returned, this Node's channel needs to still be connected server
6826 /// side, which won't be the case if the whole logical allocation has
6827 /// failed. After logical allocation or in a different logical allocation
6828 /// sub-tree there are additional potential reasons for this error. For
6829 /// example a different logical allocation (separated from this Node(s)
6830 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
6831 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
6832 /// exist and may select a different child sub-tree than the sub-tree the
6833 /// node_ref is in causing deletion of the node_ref Node. The only time
6834 /// sysmem keeps a Node around after that Node has no corresponding channel
6835 /// is when Close() is used and the Node's sub-tree has not yet failed.
6836 /// Another reason for this error is if the node_ref is an eventpair handle
6837 /// with sufficient rights, but isn't actually a real node_ref obtained from
6838 /// GetNodeRef().
6839 ///
6840 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
6841 /// eventpair handle, or doesn't have the needed rights expected on a real
6842 /// node_ref.
6843 ///
6844 /// No other failing status codes are returned by this call. However,
6845 /// sysmem may add additional codes in future, so the client should have
6846 /// sensible default handling for any failing status code.
6847 ///
6848 /// On success, is_alternate has the following meaning:
6849 /// * true - The first parent node in common between the calling node and
6850 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
6851 /// the calling Node and the node_ref Node will _not_ have both their
6852 /// constraints apply - rather sysmem will choose one or the other of
6853 /// the constraints - never both. This is because only one child of
6854 /// a BufferCollectionTokenGroup is selected during logical allocation,
6855 /// with only that one child's sub-tree contributing to constraints
6856 /// aggregation.
6857 /// * false - The first parent node in common between the calling Node and
6858 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
6859 /// this means the first parent node in common is a
6860 /// BufferCollectionToken or BufferCollection (regardless of not
6861 /// Close()ed or Close()ed). This means that the calling Node and the
6862 /// node_ref Node _may_ have both their constraints apply during
6863 /// constraints aggregation of the logical allocation, if both Node(s)
6864 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
6865 /// In this case, there is no BufferCollectionTokenGroup that will
6866 /// directly prevent the two Node(s) from both being selected and their
6867 /// constraints both aggregated, but even when false, one or both
6868 /// Node(s) may still be eliminated from consideration if one or both
6869 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
6870 /// which selects a child sub-tree other than the sub-tree containing
6871 /// the calling Node or node_ref Node.
6872 pub fn r#is_alternate_for(
6873 &self,
6874 mut node_ref: fidl::Event,
6875 ___deadline: zx::MonotonicInstant,
6876 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
6877 let _response = self.client.send_query::<
6878 NodeIsAlternateForRequest,
6879 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
6880 BufferCollectionTokenGroupMarker,
6881 >(
6882 (node_ref,),
6883 0x33a2a7aff2776c07,
6884 fidl::encoding::DynamicFlags::empty(),
6885 ___deadline,
6886 )?;
6887 Ok(_response.map(|x| x.is_alternate))
6888 }
6889
6890 /// Create a child token. Before passing the client end of this token to
6891 /// BindSharedCollection(), completion of Sync() after CreateChild() is
6892 /// required. Or the client can use CreateChildrenSync() which essentially
6893 /// includes the Sync().
6894 ///
6895 /// token_request - the server end of the new token channel.
6896 ///
6897 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
6898 /// allows the holder to get the same rights to buffers as the parent token
6899 /// (of the group) had.
6900 pub fn r#create_child(
6901 &self,
6902 mut payload: BufferCollectionTokenGroupCreateChildRequest,
6903 ) -> Result<(), fidl::Error> {
6904 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
6905 &mut payload,
6906 0x2e74f8bcbf59ee59,
6907 fidl::encoding::DynamicFlags::empty(),
6908 )
6909 }
6910
6911 /// Create 1 or more child tokens at once, synchronously. In contrast to
6912 /// CreateChild(), no Sync() completion is required before passing the
6913 /// client end of a returned token to BindSharedCollection().
6914 ///
6915 /// The size of the rights_attentuation_mask determines the number of
6916 /// created child tokens.
6917 ///
6918 /// The lower-index child tokens are higher priority (attempted sooner) than
6919 /// higher-index child tokens.
6920 ///
6921 /// As per all child tokens, successful aggregation will choose exactly one
6922 /// child among all created children (across all children created across
6923 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
6924 ///
6925 /// The maximum permissible total number of children per group, and total
6926 /// number of nodes in an overall tree (from the root) are capped to limits
6927 /// which are not configurable via these protocols.
6928 pub fn r#create_children_sync(
6929 &self,
6930 mut rights_attenuation_masks: &[fidl::Rights],
6931 ___deadline: zx::MonotonicInstant,
6932 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error> {
6933 let _response = self.client.send_query::<
6934 BufferCollectionTokenGroupCreateChildrenSyncRequest,
6935 BufferCollectionTokenGroupCreateChildrenSyncResponse,
6936 BufferCollectionTokenGroupMarker,
6937 >(
6938 (rights_attenuation_masks,),
6939 0x569dc3ca2a98f535,
6940 fidl::encoding::DynamicFlags::empty(),
6941 ___deadline,
6942 )?;
6943 Ok(_response.tokens)
6944 }
6945
6946 /// AllChildrenPresent()
6947 ///
6948 /// After creating all children, the client must call AllChildrenPresent()
6949 /// to inform sysmem that no more children will be created, so that sysmem
6950 /// can know when it's ok to start aggregating constraints.
6951 ///
6952 /// If Close() is to be sent, it should be sent _after_
6953 /// AllChildrenPresent(), else failure of the group and propagation of the
6954 /// failure to the group's parent will still be triggered.
6955 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
6956 self.client.send::<fidl::encoding::EmptyPayload>(
6957 (),
6958 0x1d41715f6f044b50,
6959 fidl::encoding::DynamicFlags::empty(),
6960 )
6961 }
6962}
6963
6964#[cfg(target_os = "fuchsia")]
6965impl From<BufferCollectionTokenGroupSynchronousProxy> for zx::NullableHandle {
6966 fn from(value: BufferCollectionTokenGroupSynchronousProxy) -> Self {
6967 value.into_channel().into()
6968 }
6969}
6970
6971#[cfg(target_os = "fuchsia")]
6972impl From<fidl::Channel> for BufferCollectionTokenGroupSynchronousProxy {
6973 fn from(value: fidl::Channel) -> Self {
6974 Self::new(value)
6975 }
6976}
6977
6978#[cfg(target_os = "fuchsia")]
6979impl fidl::endpoints::FromClient for BufferCollectionTokenGroupSynchronousProxy {
6980 type Protocol = BufferCollectionTokenGroupMarker;
6981
6982 fn from_client(value: fidl::endpoints::ClientEnd<BufferCollectionTokenGroupMarker>) -> Self {
6983 Self::new(value.into_channel())
6984 }
6985}
6986
6987#[derive(Debug, Clone)]
6988pub struct BufferCollectionTokenGroupProxy {
6989 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
6990}
6991
6992impl fidl::endpoints::Proxy for BufferCollectionTokenGroupProxy {
6993 type Protocol = BufferCollectionTokenGroupMarker;
6994
6995 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
6996 Self::new(inner)
6997 }
6998
6999 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
7000 self.client.into_channel().map_err(|client| Self { client })
7001 }
7002
7003 fn as_channel(&self) -> &::fidl::AsyncChannel {
7004 self.client.as_channel()
7005 }
7006}
7007
7008impl BufferCollectionTokenGroupProxy {
7009 /// Create a new Proxy for fuchsia.sysmem/BufferCollectionTokenGroup.
7010 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
7011 let protocol_name =
7012 <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
7013 Self { client: fidl::client::Client::new(channel, protocol_name) }
7014 }
7015
7016 /// Get a Stream of events from the remote end of the protocol.
7017 ///
7018 /// # Panics
7019 ///
7020 /// Panics if the event stream was already taken.
7021 pub fn take_event_stream(&self) -> BufferCollectionTokenGroupEventStream {
7022 BufferCollectionTokenGroupEventStream { event_receiver: self.client.take_event_receiver() }
7023 }
7024
7025 /// Ensure that previous messages, including Duplicate() messages on a
7026 /// token, collection, or group, have been received server side.
7027 ///
7028 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
7029 /// valid sysmem token risks the Sync() hanging forever. See
7030 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
7031 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
7032 /// Another way is to pass the token to BindSharedCollection(), which also
7033 /// validates the token as part of exchanging it for a BufferCollection
7034 /// channel, and BufferCollection Sync() can then be used.
7035 ///
7036 /// After a Sync(), it's then safe to send the client end of token_request
7037 /// to another participant knowing the server will recognize the token when
7038 /// it's sent into BindSharedCollection() by the other participant.
7039 ///
7040 /// Other options include waiting for each token.Duplicate() to complete
7041 /// individually (using separate call to token.Sync() after each), or
7042 /// calling Sync() on BufferCollection after the token has been turned in
7043 /// via BindSharedCollection().
7044 ///
7045 /// Another way to mitigate is to avoid calling Sync() on the token, and
7046 /// instead later deal with potential failure of BufferCollection.Sync() if
7047 /// the original token was invalid. This option can be preferable from a
7048 /// performance point of view, but requires client code to delay sending
7049 /// tokens duplicated from this token until after client code has converted
7050 /// the duplicating token to a BufferCollection and received successful
7051 /// response from BufferCollection.Sync().
7052 ///
7053 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
7054 /// When BufferCollection.Sync() isn't feasible, the caller must already
7055 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
7056 /// hang forever. See ValidateBufferCollectionToken() to check token
7057 /// validity first if the token isn't already known to be (is/was) valid.
7058 pub fn r#sync(
7059 &self,
7060 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
7061 BufferCollectionTokenGroupProxyInterface::r#sync(self)
7062 }
7063
7064 /// On a BufferCollectionToken channel:
7065 ///
7066 /// Normally a participant will convert a BufferCollectionToken into a
7067 /// BufferCollection view, but a participant is also free to Close() the
7068 /// token (and then close the channel immediately or shortly later in
7069 /// response to server closing its end), which avoids causing logical buffer
7070 /// collection failure. Â Normally an unexpected token channel close will
7071 /// cause logical buffer collection failure (the only exceptions being
7072 /// certain cases involving AttachToken() or SetDispensable()).
7073 ///
7074 /// On a BufferCollection channel:
7075 ///
7076 /// By default the server handles unexpected failure of a BufferCollection
7077 /// by failing the whole logical buffer collection. Partly this is to
7078 /// expedite closing VMO handles to reclaim memory when any participant
7079 /// fails. If a participant would like to cleanly close a BufferCollection
7080 /// view without causing logical buffer collection failure, the participant
7081 /// can send Close() before closing the client end of the BufferCollection
7082 /// channel. If this is the last BufferCollection view, the logical buffer
7083 /// collection will still go away. The Close() can occur before or after
7084 /// SetConstraints(). If before SetConstraints(), the buffer collection
7085 /// won't require constraints from this node in order to allocate. If
7086 /// after SetConstraints(), the constraints are retained and aggregated
7087 /// along with any subsequent logical allocation(s), despite the lack of
7088 /// channel connection.
7089 ///
7090 /// On a BufferCollectionTokenGroup channel:
7091 ///
7092 /// By default, unexpected failure of a BufferCollectionTokenGroup will
7093 /// trigger failure of the logical BufferCollectionTokenGroup and will
7094 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
7095 /// channel without failing the logical group or propagating failure, send
7096 /// Close() before closing the channel client endpoint.
7097 ///
7098 /// If Close() occurs before AllChildrenPresent(), the logical buffer
7099 /// collection will still fail despite the Close() (because sysmem can't be
7100 /// sure whether all relevant children were created, so it's ambiguous
7101 /// whether all relevant constraints will be provided to sysmem). If
7102 /// Close() occurs after AllChildrenPresent(), the children and all their
7103 /// constraints remain intact (just as they would if the
7104 /// BufferCollectionTokenGroup channel had remained open), and the close
7105 /// doesn't trigger or propagate failure.
7106 pub fn r#close(&self) -> Result<(), fidl::Error> {
7107 BufferCollectionTokenGroupProxyInterface::r#close(self)
7108 }
7109
7110 /// Set a name for VMOs in this buffer collection. The name may be truncated
7111 /// shorter. The name only affects VMOs allocated after it's set - this call
7112 /// does not rename existing VMOs. If multiple clients set different names
7113 /// then the larger priority value will win.
7114 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
7115 BufferCollectionTokenGroupProxyInterface::r#set_name(self, priority, name)
7116 }
7117
7118 /// Set information about the current client that can be used by sysmem to
7119 /// help debug leaking memory and hangs waiting for constraints. |name| can
7120 /// be an arbitrary string, but the current process name (see
7121 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
7122 /// arbitrary id, but the current process ID (see
7123 /// fsl::GetCurrentProcessKoid()) is a good default.
7124 ///
7125 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
7126 /// indicate which client is closing their channel first, leading to
7127 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
7128 /// over, but if happening earlier than expected, the
7129 /// client-channel-specific name can help diagnose where the failure is
7130 /// first coming from, from sysmem's point of view).
7131 ///
7132 /// By default (unless overriden by this message or using
7133 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
7134 /// parent Node at the time the child Node is created. While this can be
7135 /// better than nothing, it's often better for each participant to use
7136 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
7137 /// info directly relevant to the current client. Also, SetVerboseLogging()
7138 /// can be used to help disambiguate if a Node is suspected of having info
7139 /// that was copied from its parent.
7140 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
7141 BufferCollectionTokenGroupProxyInterface::r#set_debug_client_info(self, name, id)
7142 }
7143
7144 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
7145 /// after creating a collection. Clients can call this method to change
7146 /// when the log is printed. If multiple client set the deadline, it's
7147 /// unspecified which deadline will take effect.
7148 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
7149 BufferCollectionTokenGroupProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
7150 }
7151
7152 /// Verbose logging includes constraints set via SetConstraints() from each
7153 /// client along with info set via SetDebugClientInfo() and the structure of
7154 /// the tree of Node(s).
7155 ///
7156 /// Normally sysmem prints only a single line complaint when aggregation
7157 /// fails, with just the specific detailed reason that aggregation failed,
7158 /// with minimal context. While this is often enough to diagnose a problem
7159 /// if only a small change was made and the system had been working before
7160 /// the small change, it's often not particularly helpful for getting a new
7161 /// buffer collection to work for the first time. Especially with more
7162 /// complex trees of nodes, involving things like AttachToken(),
7163 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
7164 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
7165 /// looks like and why it's failing a logical allocation, or why a tree or
7166 /// sub-tree is failing sooner than expected.
7167 ///
7168 /// The intent of the extra logging is to be acceptable from a performance
7169 /// point of view, if only enabled on a low number of buffer collections.
7170 /// If we're not tracking down a bug, we shouldn't send this message.
7171 ///
7172 /// If too many participants leave verbose logging enabled, we may end up
7173 /// needing to require that system-wide sysmem verbose logging be permitted
7174 /// via some other setting, to avoid sysmem spamming the log too much due to
7175 /// this message.
7176 ///
7177 /// This may be a NOP for some nodes due to intentional policy associated
7178 /// with the node, if we don't trust a node enough to let it turn on verbose
7179 /// logging.
7180 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7181 BufferCollectionTokenGroupProxyInterface::r#set_verbose_logging(self)
7182 }
7183
7184 /// This gets an event handle that can be used as a parameter to
7185 /// IsAlternateFor() called on any Node. The client will not be granted the
7186 /// right to signal this event, as this handle should only be used as proof
7187 /// that the client obtained this handle from this Node.
7188 ///
7189 /// Because this is a get not a set, no Sync() is needed between the
7190 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
7191 /// potentially being on different channels.
7192 ///
7193 /// See also IsAlternateFor().
7194 pub fn r#get_node_ref(
7195 &self,
7196 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
7197 {
7198 BufferCollectionTokenGroupProxyInterface::r#get_node_ref(self)
7199 }
7200
7201 /// This checks whether the calling node is in a subtree rooted at a
7202 /// different child token of a common parent BufferCollectionTokenGroup, in
7203 /// relation to the passed-in node_ref.
7204 ///
7205 /// This call is for assisting with admission control de-duplication, and
7206 /// with debugging.
7207 ///
7208 /// The node_ref must be obtained using GetNodeRef() of a
7209 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
7210 ///
7211 /// The node_ref can be a duplicated handle; it's not necessary to call
7212 /// GetNodeRef() for every call to IsAlternateFor().
7213 ///
7214 /// If a calling token may not actually be a valid token at all due to
7215 /// a potentially hostile/untrusted provider of the token, call
7216 /// ValidateBufferCollectionToken() first instead of potentially getting
7217 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
7218 /// token not being a real token (not really talking to sysmem). Another
7219 /// option is to call BindSharedCollection with this token first which also
7220 /// validates the token along with converting it to a BufferCollection, then
7221 /// call BufferCollection IsAlternateFor().
7222 ///
7223 /// error values:
7224 ///
7225 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
7226 /// buffer collection as the calling Node. Before logical allocation and
7227 /// within the same logical allocation sub-tree, this essentially means that
7228 /// the node_ref was never part of this logical buffer collection, since
7229 /// before logical allocation all node_refs that come into existence remain
7230 /// in existence at least until logical allocation (including Node(s) that
7231 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
7232 /// to be returned, this Node's channel needs to still be connected server
7233 /// side, which won't be the case if the whole logical allocation has
7234 /// failed. After logical allocation or in a different logical allocation
7235 /// sub-tree there are additional potential reasons for this error. For
7236 /// example a different logical allocation (separated from this Node(s)
7237 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
7238 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
7239 /// exist and may select a different child sub-tree than the sub-tree the
7240 /// node_ref is in causing deletion of the node_ref Node. The only time
7241 /// sysmem keeps a Node around after that Node has no corresponding channel
7242 /// is when Close() is used and the Node's sub-tree has not yet failed.
7243 /// Another reason for this error is if the node_ref is an eventpair handle
7244 /// with sufficient rights, but isn't actually a real node_ref obtained from
7245 /// GetNodeRef().
7246 ///
7247 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
7248 /// eventpair handle, or doesn't have the needed rights expected on a real
7249 /// node_ref.
7250 ///
7251 /// No other failing status codes are returned by this call. However,
7252 /// sysmem may add additional codes in future, so the client should have
7253 /// sensible default handling for any failing status code.
7254 ///
7255 /// On success, is_alternate has the following meaning:
7256 /// * true - The first parent node in common between the calling node and
7257 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
7258 /// the calling Node and the node_ref Node will _not_ have both their
7259 /// constraints apply - rather sysmem will choose one or the other of
7260 /// the constraints - never both. This is because only one child of
7261 /// a BufferCollectionTokenGroup is selected during logical allocation,
7262 /// with only that one child's sub-tree contributing to constraints
7263 /// aggregation.
7264 /// * false - The first parent node in common between the calling Node and
7265 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
7266 /// this means the first parent node in common is a
7267 /// BufferCollectionToken or BufferCollection (regardless of not
7268 /// Close()ed or Close()ed). This means that the calling Node and the
7269 /// node_ref Node _may_ have both their constraints apply during
7270 /// constraints aggregation of the logical allocation, if both Node(s)
7271 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
7272 /// In this case, there is no BufferCollectionTokenGroup that will
7273 /// directly prevent the two Node(s) from both being selected and their
7274 /// constraints both aggregated, but even when false, one or both
7275 /// Node(s) may still be eliminated from consideration if one or both
7276 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
7277 /// which selects a child sub-tree other than the sub-tree containing
7278 /// the calling Node or node_ref Node.
7279 pub fn r#is_alternate_for(
7280 &self,
7281 mut node_ref: fidl::Event,
7282 ) -> fidl::client::QueryResponseFut<
7283 NodeIsAlternateForResult,
7284 fidl::encoding::DefaultFuchsiaResourceDialect,
7285 > {
7286 BufferCollectionTokenGroupProxyInterface::r#is_alternate_for(self, node_ref)
7287 }
7288
7289 /// Create a child token. Before passing the client end of this token to
7290 /// BindSharedCollection(), completion of Sync() after CreateChild() is
7291 /// required. Or the client can use CreateChildrenSync() which essentially
7292 /// includes the Sync().
7293 ///
7294 /// token_request - the server end of the new token channel.
7295 ///
7296 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
7297 /// allows the holder to get the same rights to buffers as the parent token
7298 /// (of the group) had.
7299 pub fn r#create_child(
7300 &self,
7301 mut payload: BufferCollectionTokenGroupCreateChildRequest,
7302 ) -> Result<(), fidl::Error> {
7303 BufferCollectionTokenGroupProxyInterface::r#create_child(self, payload)
7304 }
7305
7306 /// Create 1 or more child tokens at once, synchronously. In contrast to
7307 /// CreateChild(), no Sync() completion is required before passing the
7308 /// client end of a returned token to BindSharedCollection().
7309 ///
7310 /// The size of the rights_attentuation_mask determines the number of
7311 /// created child tokens.
7312 ///
7313 /// The lower-index child tokens are higher priority (attempted sooner) than
7314 /// higher-index child tokens.
7315 ///
7316 /// As per all child tokens, successful aggregation will choose exactly one
7317 /// child among all created children (across all children created across
7318 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
7319 ///
7320 /// The maximum permissible total number of children per group, and total
7321 /// number of nodes in an overall tree (from the root) are capped to limits
7322 /// which are not configurable via these protocols.
7323 pub fn r#create_children_sync(
7324 &self,
7325 mut rights_attenuation_masks: &[fidl::Rights],
7326 ) -> fidl::client::QueryResponseFut<
7327 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7328 fidl::encoding::DefaultFuchsiaResourceDialect,
7329 > {
7330 BufferCollectionTokenGroupProxyInterface::r#create_children_sync(
7331 self,
7332 rights_attenuation_masks,
7333 )
7334 }
7335
7336 /// AllChildrenPresent()
7337 ///
7338 /// After creating all children, the client must call AllChildrenPresent()
7339 /// to inform sysmem that no more children will be created, so that sysmem
7340 /// can know when it's ok to start aggregating constraints.
7341 ///
7342 /// If Close() is to be sent, it should be sent _after_
7343 /// AllChildrenPresent(), else failure of the group and propagation of the
7344 /// failure to the group's parent will still be triggered.
7345 pub fn r#all_children_present(&self) -> Result<(), fidl::Error> {
7346 BufferCollectionTokenGroupProxyInterface::r#all_children_present(self)
7347 }
7348}
7349
7350impl BufferCollectionTokenGroupProxyInterface for BufferCollectionTokenGroupProxy {
7351 type SyncResponseFut =
7352 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
7353 fn r#sync(&self) -> Self::SyncResponseFut {
7354 fn _decode(
7355 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7356 ) -> Result<(), fidl::Error> {
7357 let _response = fidl::client::decode_transaction_body::<
7358 fidl::encoding::EmptyPayload,
7359 fidl::encoding::DefaultFuchsiaResourceDialect,
7360 0x4577e238ae26291,
7361 >(_buf?)?;
7362 Ok(_response)
7363 }
7364 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
7365 (),
7366 0x4577e238ae26291,
7367 fidl::encoding::DynamicFlags::empty(),
7368 _decode,
7369 )
7370 }
7371
7372 fn r#close(&self) -> Result<(), fidl::Error> {
7373 self.client.send::<fidl::encoding::EmptyPayload>(
7374 (),
7375 0x5b1d7a4f5681fca7,
7376 fidl::encoding::DynamicFlags::empty(),
7377 )
7378 }
7379
7380 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
7381 self.client.send::<NodeSetNameRequest>(
7382 (priority, name),
7383 0x77a41bb6217e2443,
7384 fidl::encoding::DynamicFlags::empty(),
7385 )
7386 }
7387
7388 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
7389 self.client.send::<NodeSetDebugClientInfoRequest>(
7390 (name, id),
7391 0x7275759070eb5ee2,
7392 fidl::encoding::DynamicFlags::empty(),
7393 )
7394 }
7395
7396 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
7397 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
7398 (deadline,),
7399 0x46d38f4772638867,
7400 fidl::encoding::DynamicFlags::empty(),
7401 )
7402 }
7403
7404 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
7405 self.client.send::<fidl::encoding::EmptyPayload>(
7406 (),
7407 0x6bfbe2cf1701d288,
7408 fidl::encoding::DynamicFlags::empty(),
7409 )
7410 }
7411
7412 type GetNodeRefResponseFut =
7413 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
7414 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
7415 fn _decode(
7416 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7417 ) -> Result<fidl::Event, fidl::Error> {
7418 let _response = fidl::client::decode_transaction_body::<
7419 NodeGetNodeRefResponse,
7420 fidl::encoding::DefaultFuchsiaResourceDialect,
7421 0x467b7c75c35c3b84,
7422 >(_buf?)?;
7423 Ok(_response.node_ref)
7424 }
7425 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
7426 (),
7427 0x467b7c75c35c3b84,
7428 fidl::encoding::DynamicFlags::empty(),
7429 _decode,
7430 )
7431 }
7432
7433 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
7434 NodeIsAlternateForResult,
7435 fidl::encoding::DefaultFuchsiaResourceDialect,
7436 >;
7437 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
7438 fn _decode(
7439 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7440 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
7441 let _response = fidl::client::decode_transaction_body::<
7442 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
7443 fidl::encoding::DefaultFuchsiaResourceDialect,
7444 0x33a2a7aff2776c07,
7445 >(_buf?)?;
7446 Ok(_response.map(|x| x.is_alternate))
7447 }
7448 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
7449 (node_ref,),
7450 0x33a2a7aff2776c07,
7451 fidl::encoding::DynamicFlags::empty(),
7452 _decode,
7453 )
7454 }
7455
7456 fn r#create_child(
7457 &self,
7458 mut payload: BufferCollectionTokenGroupCreateChildRequest,
7459 ) -> Result<(), fidl::Error> {
7460 self.client.send::<BufferCollectionTokenGroupCreateChildRequest>(
7461 &mut payload,
7462 0x2e74f8bcbf59ee59,
7463 fidl::encoding::DynamicFlags::empty(),
7464 )
7465 }
7466
7467 type CreateChildrenSyncResponseFut = fidl::client::QueryResponseFut<
7468 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7469 fidl::encoding::DefaultFuchsiaResourceDialect,
7470 >;
7471 fn r#create_children_sync(
7472 &self,
7473 mut rights_attenuation_masks: &[fidl::Rights],
7474 ) -> Self::CreateChildrenSyncResponseFut {
7475 fn _decode(
7476 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
7477 ) -> Result<Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>, fidl::Error>
7478 {
7479 let _response = fidl::client::decode_transaction_body::<
7480 BufferCollectionTokenGroupCreateChildrenSyncResponse,
7481 fidl::encoding::DefaultFuchsiaResourceDialect,
7482 0x569dc3ca2a98f535,
7483 >(_buf?)?;
7484 Ok(_response.tokens)
7485 }
7486 self.client.send_query_and_decode::<
7487 BufferCollectionTokenGroupCreateChildrenSyncRequest,
7488 Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
7489 >(
7490 (rights_attenuation_masks,),
7491 0x569dc3ca2a98f535,
7492 fidl::encoding::DynamicFlags::empty(),
7493 _decode,
7494 )
7495 }
7496
7497 fn r#all_children_present(&self) -> Result<(), fidl::Error> {
7498 self.client.send::<fidl::encoding::EmptyPayload>(
7499 (),
7500 0x1d41715f6f044b50,
7501 fidl::encoding::DynamicFlags::empty(),
7502 )
7503 }
7504}
7505
7506pub struct BufferCollectionTokenGroupEventStream {
7507 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
7508}
7509
7510impl std::marker::Unpin for BufferCollectionTokenGroupEventStream {}
7511
7512impl futures::stream::FusedStream for BufferCollectionTokenGroupEventStream {
7513 fn is_terminated(&self) -> bool {
7514 self.event_receiver.is_terminated()
7515 }
7516}
7517
7518impl futures::Stream for BufferCollectionTokenGroupEventStream {
7519 type Item = Result<BufferCollectionTokenGroupEvent, fidl::Error>;
7520
7521 fn poll_next(
7522 mut self: std::pin::Pin<&mut Self>,
7523 cx: &mut std::task::Context<'_>,
7524 ) -> std::task::Poll<Option<Self::Item>> {
7525 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
7526 &mut self.event_receiver,
7527 cx
7528 )?) {
7529 Some(buf) => std::task::Poll::Ready(Some(BufferCollectionTokenGroupEvent::decode(buf))),
7530 None => std::task::Poll::Ready(None),
7531 }
7532 }
7533}
7534
7535#[derive(Debug)]
7536pub enum BufferCollectionTokenGroupEvent {}
7537
7538impl BufferCollectionTokenGroupEvent {
7539 /// Decodes a message buffer as a [`BufferCollectionTokenGroupEvent`].
7540 fn decode(
7541 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
7542 ) -> Result<BufferCollectionTokenGroupEvent, fidl::Error> {
7543 let (bytes, _handles) = buf.split_mut();
7544 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7545 debug_assert_eq!(tx_header.tx_id, 0);
7546 match tx_header.ordinal {
7547 _ => Err(fidl::Error::UnknownOrdinal {
7548 ordinal: tx_header.ordinal,
7549 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
7550 })
7551 }
7552 }
7553}
7554
7555/// A Stream of incoming requests for fuchsia.sysmem/BufferCollectionTokenGroup.
7556pub struct BufferCollectionTokenGroupRequestStream {
7557 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7558 is_terminated: bool,
7559}
7560
7561impl std::marker::Unpin for BufferCollectionTokenGroupRequestStream {}
7562
7563impl futures::stream::FusedStream for BufferCollectionTokenGroupRequestStream {
7564 fn is_terminated(&self) -> bool {
7565 self.is_terminated
7566 }
7567}
7568
7569impl fidl::endpoints::RequestStream for BufferCollectionTokenGroupRequestStream {
7570 type Protocol = BufferCollectionTokenGroupMarker;
7571 type ControlHandle = BufferCollectionTokenGroupControlHandle;
7572
7573 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
7574 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
7575 }
7576
7577 fn control_handle(&self) -> Self::ControlHandle {
7578 BufferCollectionTokenGroupControlHandle { inner: self.inner.clone() }
7579 }
7580
7581 fn into_inner(
7582 self,
7583 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
7584 {
7585 (self.inner, self.is_terminated)
7586 }
7587
7588 fn from_inner(
7589 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
7590 is_terminated: bool,
7591 ) -> Self {
7592 Self { inner, is_terminated }
7593 }
7594}
7595
7596impl futures::Stream for BufferCollectionTokenGroupRequestStream {
7597 type Item = Result<BufferCollectionTokenGroupRequest, fidl::Error>;
7598
7599 fn poll_next(
7600 mut self: std::pin::Pin<&mut Self>,
7601 cx: &mut std::task::Context<'_>,
7602 ) -> std::task::Poll<Option<Self::Item>> {
7603 let this = &mut *self;
7604 if this.inner.check_shutdown(cx) {
7605 this.is_terminated = true;
7606 return std::task::Poll::Ready(None);
7607 }
7608 if this.is_terminated {
7609 panic!("polled BufferCollectionTokenGroupRequestStream after completion");
7610 }
7611 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
7612 |bytes, handles| {
7613 match this.inner.channel().read_etc(cx, bytes, handles) {
7614 std::task::Poll::Ready(Ok(())) => {}
7615 std::task::Poll::Pending => return std::task::Poll::Pending,
7616 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
7617 this.is_terminated = true;
7618 return std::task::Poll::Ready(None);
7619 }
7620 std::task::Poll::Ready(Err(e)) => {
7621 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
7622 e.into(),
7623 ))));
7624 }
7625 }
7626
7627 // A message has been received from the channel
7628 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
7629
7630 std::task::Poll::Ready(Some(match header.ordinal {
7631 0x4577e238ae26291 => {
7632 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7633 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7634 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7635 let control_handle = BufferCollectionTokenGroupControlHandle {
7636 inner: this.inner.clone(),
7637 };
7638 Ok(BufferCollectionTokenGroupRequest::Sync {
7639 responder: BufferCollectionTokenGroupSyncResponder {
7640 control_handle: std::mem::ManuallyDrop::new(control_handle),
7641 tx_id: header.tx_id,
7642 },
7643 })
7644 }
7645 0x5b1d7a4f5681fca7 => {
7646 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7647 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7648 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7649 let control_handle = BufferCollectionTokenGroupControlHandle {
7650 inner: this.inner.clone(),
7651 };
7652 Ok(BufferCollectionTokenGroupRequest::Close {
7653 control_handle,
7654 })
7655 }
7656 0x77a41bb6217e2443 => {
7657 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7658 let mut req = fidl::new_empty!(NodeSetNameRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7659 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
7660 let control_handle = BufferCollectionTokenGroupControlHandle {
7661 inner: this.inner.clone(),
7662 };
7663 Ok(BufferCollectionTokenGroupRequest::SetName {priority: req.priority,
7664name: req.name,
7665
7666 control_handle,
7667 })
7668 }
7669 0x7275759070eb5ee2 => {
7670 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7671 let mut req = fidl::new_empty!(NodeSetDebugClientInfoRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7672 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
7673 let control_handle = BufferCollectionTokenGroupControlHandle {
7674 inner: this.inner.clone(),
7675 };
7676 Ok(BufferCollectionTokenGroupRequest::SetDebugClientInfo {name: req.name,
7677id: req.id,
7678
7679 control_handle,
7680 })
7681 }
7682 0x46d38f4772638867 => {
7683 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7684 let mut req = fidl::new_empty!(NodeSetDebugTimeoutLogDeadlineRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7685 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
7686 let control_handle = BufferCollectionTokenGroupControlHandle {
7687 inner: this.inner.clone(),
7688 };
7689 Ok(BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {deadline: req.deadline,
7690
7691 control_handle,
7692 })
7693 }
7694 0x6bfbe2cf1701d288 => {
7695 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7696 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7697 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7698 let control_handle = BufferCollectionTokenGroupControlHandle {
7699 inner: this.inner.clone(),
7700 };
7701 Ok(BufferCollectionTokenGroupRequest::SetVerboseLogging {
7702 control_handle,
7703 })
7704 }
7705 0x467b7c75c35c3b84 => {
7706 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7707 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7708 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7709 let control_handle = BufferCollectionTokenGroupControlHandle {
7710 inner: this.inner.clone(),
7711 };
7712 Ok(BufferCollectionTokenGroupRequest::GetNodeRef {
7713 responder: BufferCollectionTokenGroupGetNodeRefResponder {
7714 control_handle: std::mem::ManuallyDrop::new(control_handle),
7715 tx_id: header.tx_id,
7716 },
7717 })
7718 }
7719 0x33a2a7aff2776c07 => {
7720 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7721 let mut req = fidl::new_empty!(NodeIsAlternateForRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7722 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
7723 let control_handle = BufferCollectionTokenGroupControlHandle {
7724 inner: this.inner.clone(),
7725 };
7726 Ok(BufferCollectionTokenGroupRequest::IsAlternateFor {node_ref: req.node_ref,
7727
7728 responder: BufferCollectionTokenGroupIsAlternateForResponder {
7729 control_handle: std::mem::ManuallyDrop::new(control_handle),
7730 tx_id: header.tx_id,
7731 },
7732 })
7733 }
7734 0x2e74f8bcbf59ee59 => {
7735 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7736 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7737 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildRequest>(&header, _body_bytes, handles, &mut req)?;
7738 let control_handle = BufferCollectionTokenGroupControlHandle {
7739 inner: this.inner.clone(),
7740 };
7741 Ok(BufferCollectionTokenGroupRequest::CreateChild {payload: req,
7742 control_handle,
7743 })
7744 }
7745 0x569dc3ca2a98f535 => {
7746 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
7747 let mut req = fidl::new_empty!(BufferCollectionTokenGroupCreateChildrenSyncRequest, fidl::encoding::DefaultFuchsiaResourceDialect);
7748 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<BufferCollectionTokenGroupCreateChildrenSyncRequest>(&header, _body_bytes, handles, &mut req)?;
7749 let control_handle = BufferCollectionTokenGroupControlHandle {
7750 inner: this.inner.clone(),
7751 };
7752 Ok(BufferCollectionTokenGroupRequest::CreateChildrenSync {rights_attenuation_masks: req.rights_attenuation_masks,
7753
7754 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder {
7755 control_handle: std::mem::ManuallyDrop::new(control_handle),
7756 tx_id: header.tx_id,
7757 },
7758 })
7759 }
7760 0x1d41715f6f044b50 => {
7761 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
7762 let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
7763 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
7764 let control_handle = BufferCollectionTokenGroupControlHandle {
7765 inner: this.inner.clone(),
7766 };
7767 Ok(BufferCollectionTokenGroupRequest::AllChildrenPresent {
7768 control_handle,
7769 })
7770 }
7771 _ => Err(fidl::Error::UnknownOrdinal {
7772 ordinal: header.ordinal,
7773 protocol_name: <BufferCollectionTokenGroupMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
7774 }),
7775 }))
7776 },
7777 )
7778 }
7779}
7780
7781/// The sysmem implementation is guaranteed to be consistent with a logical /
7782/// conceptual model as follows:
7783///
7784/// As usual, a logical allocation considers either the root and all nodes with
7785/// connectivity to the root that don't transit an AttachToken(), or a sub-tree
7786/// rooted at an AttachToken() token and all nodes with connectivity to that
7787/// subtree that don't transit another AttachToken(). This is called the
7788/// logical allocation pruned sub-tree, or pruned sub-tree for short.
7789///
7790/// During constraints aggregation, each BufferCollectionTokenGroup will select
7791/// a single child token among its children. The rest of the children will
7792/// appear to fail the logical allocation, while the selected child may succeed.
7793///
7794/// When more than one BufferCollectionTokenGroup exists in the overall logical
7795/// allocation pruned sub-tree, the relative priority between two groups is
7796/// equivalent to their ordering in a DFS pre-order iteration of the tree, with
7797/// parents higher priority than children, and left children higher priority
7798/// than right children.
7799///
7800/// When a particular child of a group is selected (whether provisionally during
7801/// a constraints aggregation attempt, or as a final selection), the
7802/// non-selection of other children of the group can potentially "hide" other
7803/// groups under those non-selected children.
7804///
7805/// Within a logical allocation, aggregation is attempted first by provisionally
7806/// selecting the child 0 of the highest-priority group, and child 0 of the next
7807/// highest-priority group that isn't hidden by the provisional selections so
7808/// far, etc.
7809///
7810/// If that aggregation attempt fails, aggregation will be attempted with the
7811/// ordinal 0 child of all the same groups except the lowest priority non-hidden
7812/// group which will provisionally select its ordinal 1 child (and then child 2
7813/// and so on). If a new lowest-priority group is un-hidden as provisional
7814/// selections are updated, that newly un-hidden lowest-priority group has all
7815/// its children considered in order, before changing the provisional selection
7816/// in the former lowest-priority group. In terms of result, this is equivalent
7817/// to systematic enumeration of all possible combinations of choices in a
7818/// counting-like order updating the lowest-priority group the most often and
7819/// the highest-priority group the least often. Rather than actually attempting
7820/// aggregation with all the combinations, we can skip over combinations which
7821/// are redundant/equivalent due to hiding without any change to the result.
7822///
7823/// Attempted aggregations of enumerated non-equivalent combinations of choices
7824/// continue in this manner until either (a) all aggregation attempts fail in
7825/// which case the overall logical allocation fails, or (b) until an attempted
7826/// aggregation succeeds, in which case buffer allocation (if needed) is
7827/// attempted once. If buffer allocation based on the first successful
7828/// aggregation fails, the overall logical allocation fails (there is no buffer
7829/// allocation retry / re-attempt). If buffer allocation succeeds (or is not
7830/// needed), the logical allocation succeeds.
7831///
7832/// If this prioritization scheme cannot reasonably work for your usage of
7833/// sysmem, please contact sysmem folks to discuss potentially adding a way to
7834/// achieve what you need.
7835///
7836/// Please avoid creating a large number of BufferCollectionTokenGroup(s) per
7837/// logical allocation, especially with large number of children overall, and
7838/// especially in cases where aggregation may reasonably be expected to often
7839/// fail using ordinal 0 children and possibly with later children as well. We
7840/// anticipate mitigating potentially high time complexity of evaluating too
7841/// many child combinations/selections across too many groups by simply failing
7842/// logical allocation beyond a certain (fairly high, but not huge) max number
7843/// of considered group child combinations/selections. More advanced (and more
7844/// complicated) mitigation is not anticipated to be practically necessary or
7845/// worth the added complexity. Please contact sysmem folks if the max limit
7846/// is getting hit or if you anticipate it getting hit, to discuss potential
7847/// options.
7848///
7849/// Prefer to use multiple ImageFormatConstraints in a single
7850/// BufferCollectionConstraints when feasible (when a participant just needs to
7851/// express the ability to work with more than a single PixelFormat, with
7852/// sysmem choosing which PixelFormat to use among those supported by all
7853/// participants).
7854///
7855/// Similar to BufferCollectionToken and BufferCollection, closure of the
7856/// BufferCollectionTokenGroup channel without sending Close() first will cause
7857/// logical buffer collection failure (or sub-tree failure if using
7858/// SetDispensable() or AttachToken() and the BufferCollectionTokenGroup is part
7859/// of a sub-tree under such a node that doesn't propagate failure to its
7860/// parent).
7861#[derive(Debug)]
7862pub enum BufferCollectionTokenGroupRequest {
7863 /// Ensure that previous messages, including Duplicate() messages on a
7864 /// token, collection, or group, have been received server side.
7865 ///
7866 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
7867 /// valid sysmem token risks the Sync() hanging forever. See
7868 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
7869 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
7870 /// Another way is to pass the token to BindSharedCollection(), which also
7871 /// validates the token as part of exchanging it for a BufferCollection
7872 /// channel, and BufferCollection Sync() can then be used.
7873 ///
7874 /// After a Sync(), it's then safe to send the client end of token_request
7875 /// to another participant knowing the server will recognize the token when
7876 /// it's sent into BindSharedCollection() by the other participant.
7877 ///
7878 /// Other options include waiting for each token.Duplicate() to complete
7879 /// individually (using separate call to token.Sync() after each), or
7880 /// calling Sync() on BufferCollection after the token has been turned in
7881 /// via BindSharedCollection().
7882 ///
7883 /// Another way to mitigate is to avoid calling Sync() on the token, and
7884 /// instead later deal with potential failure of BufferCollection.Sync() if
7885 /// the original token was invalid. This option can be preferable from a
7886 /// performance point of view, but requires client code to delay sending
7887 /// tokens duplicated from this token until after client code has converted
7888 /// the duplicating token to a BufferCollection and received successful
7889 /// response from BufferCollection.Sync().
7890 ///
7891 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
7892 /// When BufferCollection.Sync() isn't feasible, the caller must already
7893 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
7894 /// hang forever. See ValidateBufferCollectionToken() to check token
7895 /// validity first if the token isn't already known to be (is/was) valid.
7896 Sync { responder: BufferCollectionTokenGroupSyncResponder },
7897 /// On a BufferCollectionToken channel:
7898 ///
7899 /// Normally a participant will convert a BufferCollectionToken into a
7900 /// BufferCollection view, but a participant is also free to Close() the
7901 /// token (and then close the channel immediately or shortly later in
7902 /// response to server closing its end), which avoids causing logical buffer
7903 /// collection failure. Â Normally an unexpected token channel close will
7904 /// cause logical buffer collection failure (the only exceptions being
7905 /// certain cases involving AttachToken() or SetDispensable()).
7906 ///
7907 /// On a BufferCollection channel:
7908 ///
7909 /// By default the server handles unexpected failure of a BufferCollection
7910 /// by failing the whole logical buffer collection. Partly this is to
7911 /// expedite closing VMO handles to reclaim memory when any participant
7912 /// fails. If a participant would like to cleanly close a BufferCollection
7913 /// view without causing logical buffer collection failure, the participant
7914 /// can send Close() before closing the client end of the BufferCollection
7915 /// channel. If this is the last BufferCollection view, the logical buffer
7916 /// collection will still go away. The Close() can occur before or after
7917 /// SetConstraints(). If before SetConstraints(), the buffer collection
7918 /// won't require constraints from this node in order to allocate. If
7919 /// after SetConstraints(), the constraints are retained and aggregated
7920 /// along with any subsequent logical allocation(s), despite the lack of
7921 /// channel connection.
7922 ///
7923 /// On a BufferCollectionTokenGroup channel:
7924 ///
7925 /// By default, unexpected failure of a BufferCollectionTokenGroup will
7926 /// trigger failure of the logical BufferCollectionTokenGroup and will
7927 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
7928 /// channel without failing the logical group or propagating failure, send
7929 /// Close() before closing the channel client endpoint.
7930 ///
7931 /// If Close() occurs before AllChildrenPresent(), the logical buffer
7932 /// collection will still fail despite the Close() (because sysmem can't be
7933 /// sure whether all relevant children were created, so it's ambiguous
7934 /// whether all relevant constraints will be provided to sysmem). If
7935 /// Close() occurs after AllChildrenPresent(), the children and all their
7936 /// constraints remain intact (just as they would if the
7937 /// BufferCollectionTokenGroup channel had remained open), and the close
7938 /// doesn't trigger or propagate failure.
7939 Close { control_handle: BufferCollectionTokenGroupControlHandle },
7940 /// Set a name for VMOs in this buffer collection. The name may be truncated
7941 /// shorter. The name only affects VMOs allocated after it's set - this call
7942 /// does not rename existing VMOs. If multiple clients set different names
7943 /// then the larger priority value will win.
7944 SetName { priority: u32, name: String, control_handle: BufferCollectionTokenGroupControlHandle },
7945 /// Set information about the current client that can be used by sysmem to
7946 /// help debug leaking memory and hangs waiting for constraints. |name| can
7947 /// be an arbitrary string, but the current process name (see
7948 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
7949 /// arbitrary id, but the current process ID (see
7950 /// fsl::GetCurrentProcessKoid()) is a good default.
7951 ///
7952 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
7953 /// indicate which client is closing their channel first, leading to
7954 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
7955 /// over, but if happening earlier than expected, the
7956 /// client-channel-specific name can help diagnose where the failure is
7957 /// first coming from, from sysmem's point of view).
7958 ///
7959 /// By default (unless overriden by this message or using
7960 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
7961 /// parent Node at the time the child Node is created. While this can be
7962 /// better than nothing, it's often better for each participant to use
7963 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
7964 /// info directly relevant to the current client. Also, SetVerboseLogging()
7965 /// can be used to help disambiguate if a Node is suspected of having info
7966 /// that was copied from its parent.
7967 SetDebugClientInfo {
7968 name: String,
7969 id: u64,
7970 control_handle: BufferCollectionTokenGroupControlHandle,
7971 },
7972 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
7973 /// after creating a collection. Clients can call this method to change
7974 /// when the log is printed. If multiple client set the deadline, it's
7975 /// unspecified which deadline will take effect.
7976 SetDebugTimeoutLogDeadline {
7977 deadline: i64,
7978 control_handle: BufferCollectionTokenGroupControlHandle,
7979 },
7980 /// Verbose logging includes constraints set via SetConstraints() from each
7981 /// client along with info set via SetDebugClientInfo() and the structure of
7982 /// the tree of Node(s).
7983 ///
7984 /// Normally sysmem prints only a single line complaint when aggregation
7985 /// fails, with just the specific detailed reason that aggregation failed,
7986 /// with minimal context. While this is often enough to diagnose a problem
7987 /// if only a small change was made and the system had been working before
7988 /// the small change, it's often not particularly helpful for getting a new
7989 /// buffer collection to work for the first time. Especially with more
7990 /// complex trees of nodes, involving things like AttachToken(),
7991 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
7992 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
7993 /// looks like and why it's failing a logical allocation, or why a tree or
7994 /// sub-tree is failing sooner than expected.
7995 ///
7996 /// The intent of the extra logging is to be acceptable from a performance
7997 /// point of view, if only enabled on a low number of buffer collections.
7998 /// If we're not tracking down a bug, we shouldn't send this message.
7999 ///
8000 /// If too many participants leave verbose logging enabled, we may end up
8001 /// needing to require that system-wide sysmem verbose logging be permitted
8002 /// via some other setting, to avoid sysmem spamming the log too much due to
8003 /// this message.
8004 ///
8005 /// This may be a NOP for some nodes due to intentional policy associated
8006 /// with the node, if we don't trust a node enough to let it turn on verbose
8007 /// logging.
8008 SetVerboseLogging { control_handle: BufferCollectionTokenGroupControlHandle },
8009 /// This gets an event handle that can be used as a parameter to
8010 /// IsAlternateFor() called on any Node. The client will not be granted the
8011 /// right to signal this event, as this handle should only be used as proof
8012 /// that the client obtained this handle from this Node.
8013 ///
8014 /// Because this is a get not a set, no Sync() is needed between the
8015 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
8016 /// potentially being on different channels.
8017 ///
8018 /// See also IsAlternateFor().
8019 GetNodeRef { responder: BufferCollectionTokenGroupGetNodeRefResponder },
8020 /// This checks whether the calling node is in a subtree rooted at a
8021 /// different child token of a common parent BufferCollectionTokenGroup, in
8022 /// relation to the passed-in node_ref.
8023 ///
8024 /// This call is for assisting with admission control de-duplication, and
8025 /// with debugging.
8026 ///
8027 /// The node_ref must be obtained using GetNodeRef() of a
8028 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
8029 ///
8030 /// The node_ref can be a duplicated handle; it's not necessary to call
8031 /// GetNodeRef() for every call to IsAlternateFor().
8032 ///
8033 /// If a calling token may not actually be a valid token at all due to
8034 /// a potentially hostile/untrusted provider of the token, call
8035 /// ValidateBufferCollectionToken() first instead of potentially getting
8036 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
8037 /// token not being a real token (not really talking to sysmem). Another
8038 /// option is to call BindSharedCollection with this token first which also
8039 /// validates the token along with converting it to a BufferCollection, then
8040 /// call BufferCollection IsAlternateFor().
8041 ///
8042 /// error values:
8043 ///
8044 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
8045 /// buffer collection as the calling Node. Before logical allocation and
8046 /// within the same logical allocation sub-tree, this essentially means that
8047 /// the node_ref was never part of this logical buffer collection, since
8048 /// before logical allocation all node_refs that come into existence remain
8049 /// in existence at least until logical allocation (including Node(s) that
8050 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
8051 /// to be returned, this Node's channel needs to still be connected server
8052 /// side, which won't be the case if the whole logical allocation has
8053 /// failed. After logical allocation or in a different logical allocation
8054 /// sub-tree there are additional potential reasons for this error. For
8055 /// example a different logical allocation (separated from this Node(s)
8056 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
8057 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
8058 /// exist and may select a different child sub-tree than the sub-tree the
8059 /// node_ref is in causing deletion of the node_ref Node. The only time
8060 /// sysmem keeps a Node around after that Node has no corresponding channel
8061 /// is when Close() is used and the Node's sub-tree has not yet failed.
8062 /// Another reason for this error is if the node_ref is an eventpair handle
8063 /// with sufficient rights, but isn't actually a real node_ref obtained from
8064 /// GetNodeRef().
8065 ///
8066 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
8067 /// eventpair handle, or doesn't have the needed rights expected on a real
8068 /// node_ref.
8069 ///
8070 /// No other failing status codes are returned by this call. However,
8071 /// sysmem may add additional codes in future, so the client should have
8072 /// sensible default handling for any failing status code.
8073 ///
8074 /// On success, is_alternate has the following meaning:
8075 /// * true - The first parent node in common between the calling node and
8076 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
8077 /// the calling Node and the node_ref Node will _not_ have both their
8078 /// constraints apply - rather sysmem will choose one or the other of
8079 /// the constraints - never both. This is because only one child of
8080 /// a BufferCollectionTokenGroup is selected during logical allocation,
8081 /// with only that one child's sub-tree contributing to constraints
8082 /// aggregation.
8083 /// * false - The first parent node in common between the calling Node and
8084 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
8085 /// this means the first parent node in common is a
8086 /// BufferCollectionToken or BufferCollection (regardless of not
8087 /// Close()ed or Close()ed). This means that the calling Node and the
8088 /// node_ref Node _may_ have both their constraints apply during
8089 /// constraints aggregation of the logical allocation, if both Node(s)
8090 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
8091 /// In this case, there is no BufferCollectionTokenGroup that will
8092 /// directly prevent the two Node(s) from both being selected and their
8093 /// constraints both aggregated, but even when false, one or both
8094 /// Node(s) may still be eliminated from consideration if one or both
8095 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
8096 /// which selects a child sub-tree other than the sub-tree containing
8097 /// the calling Node or node_ref Node.
8098 IsAlternateFor {
8099 node_ref: fidl::Event,
8100 responder: BufferCollectionTokenGroupIsAlternateForResponder,
8101 },
8102 /// Create a child token. Before passing the client end of this token to
8103 /// BindSharedCollection(), completion of Sync() after CreateChild() is
8104 /// required. Or the client can use CreateChildrenSync() which essentially
8105 /// includes the Sync().
8106 ///
8107 /// token_request - the server end of the new token channel.
8108 ///
8109 /// rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token
8110 /// allows the holder to get the same rights to buffers as the parent token
8111 /// (of the group) had.
8112 CreateChild {
8113 payload: BufferCollectionTokenGroupCreateChildRequest,
8114 control_handle: BufferCollectionTokenGroupControlHandle,
8115 },
8116 /// Create 1 or more child tokens at once, synchronously. In contrast to
8117 /// CreateChild(), no Sync() completion is required before passing the
8118 /// client end of a returned token to BindSharedCollection().
8119 ///
8120 /// The size of the rights_attentuation_mask determines the number of
8121 /// created child tokens.
8122 ///
8123 /// The lower-index child tokens are higher priority (attempted sooner) than
8124 /// higher-index child tokens.
8125 ///
8126 /// As per all child tokens, successful aggregation will choose exactly one
8127 /// child among all created children (across all children created across
8128 /// potentially multiple calls to CreateChild() and CreateChildrenSync()).
8129 ///
8130 /// The maximum permissible total number of children per group, and total
8131 /// number of nodes in an overall tree (from the root) are capped to limits
8132 /// which are not configurable via these protocols.
8133 CreateChildrenSync {
8134 rights_attenuation_masks: Vec<fidl::Rights>,
8135 responder: BufferCollectionTokenGroupCreateChildrenSyncResponder,
8136 },
8137 /// AllChildrenPresent()
8138 ///
8139 /// After creating all children, the client must call AllChildrenPresent()
8140 /// to inform sysmem that no more children will be created, so that sysmem
8141 /// can know when it's ok to start aggregating constraints.
8142 ///
8143 /// If Close() is to be sent, it should be sent _after_
8144 /// AllChildrenPresent(), else failure of the group and propagation of the
8145 /// failure to the group's parent will still be triggered.
8146 AllChildrenPresent { control_handle: BufferCollectionTokenGroupControlHandle },
8147}
8148
8149impl BufferCollectionTokenGroupRequest {
8150 #[allow(irrefutable_let_patterns)]
8151 pub fn into_sync(self) -> Option<(BufferCollectionTokenGroupSyncResponder)> {
8152 if let BufferCollectionTokenGroupRequest::Sync { responder } = self {
8153 Some((responder))
8154 } else {
8155 None
8156 }
8157 }
8158
8159 #[allow(irrefutable_let_patterns)]
8160 pub fn into_close(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8161 if let BufferCollectionTokenGroupRequest::Close { control_handle } = self {
8162 Some((control_handle))
8163 } else {
8164 None
8165 }
8166 }
8167
8168 #[allow(irrefutable_let_patterns)]
8169 pub fn into_set_name(self) -> Option<(u32, String, BufferCollectionTokenGroupControlHandle)> {
8170 if let BufferCollectionTokenGroupRequest::SetName { priority, name, control_handle } = self
8171 {
8172 Some((priority, name, control_handle))
8173 } else {
8174 None
8175 }
8176 }
8177
8178 #[allow(irrefutable_let_patterns)]
8179 pub fn into_set_debug_client_info(
8180 self,
8181 ) -> Option<(String, u64, BufferCollectionTokenGroupControlHandle)> {
8182 if let BufferCollectionTokenGroupRequest::SetDebugClientInfo { name, id, control_handle } =
8183 self
8184 {
8185 Some((name, id, control_handle))
8186 } else {
8187 None
8188 }
8189 }
8190
8191 #[allow(irrefutable_let_patterns)]
8192 pub fn into_set_debug_timeout_log_deadline(
8193 self,
8194 ) -> Option<(i64, BufferCollectionTokenGroupControlHandle)> {
8195 if let BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline {
8196 deadline,
8197 control_handle,
8198 } = self
8199 {
8200 Some((deadline, control_handle))
8201 } else {
8202 None
8203 }
8204 }
8205
8206 #[allow(irrefutable_let_patterns)]
8207 pub fn into_set_verbose_logging(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8208 if let BufferCollectionTokenGroupRequest::SetVerboseLogging { control_handle } = self {
8209 Some((control_handle))
8210 } else {
8211 None
8212 }
8213 }
8214
8215 #[allow(irrefutable_let_patterns)]
8216 pub fn into_get_node_ref(self) -> Option<(BufferCollectionTokenGroupGetNodeRefResponder)> {
8217 if let BufferCollectionTokenGroupRequest::GetNodeRef { responder } = self {
8218 Some((responder))
8219 } else {
8220 None
8221 }
8222 }
8223
8224 #[allow(irrefutable_let_patterns)]
8225 pub fn into_is_alternate_for(
8226 self,
8227 ) -> Option<(fidl::Event, BufferCollectionTokenGroupIsAlternateForResponder)> {
8228 if let BufferCollectionTokenGroupRequest::IsAlternateFor { node_ref, responder } = self {
8229 Some((node_ref, responder))
8230 } else {
8231 None
8232 }
8233 }
8234
8235 #[allow(irrefutable_let_patterns)]
8236 pub fn into_create_child(
8237 self,
8238 ) -> Option<(
8239 BufferCollectionTokenGroupCreateChildRequest,
8240 BufferCollectionTokenGroupControlHandle,
8241 )> {
8242 if let BufferCollectionTokenGroupRequest::CreateChild { payload, control_handle } = self {
8243 Some((payload, control_handle))
8244 } else {
8245 None
8246 }
8247 }
8248
8249 #[allow(irrefutable_let_patterns)]
8250 pub fn into_create_children_sync(
8251 self,
8252 ) -> Option<(Vec<fidl::Rights>, BufferCollectionTokenGroupCreateChildrenSyncResponder)> {
8253 if let BufferCollectionTokenGroupRequest::CreateChildrenSync {
8254 rights_attenuation_masks,
8255 responder,
8256 } = self
8257 {
8258 Some((rights_attenuation_masks, responder))
8259 } else {
8260 None
8261 }
8262 }
8263
8264 #[allow(irrefutable_let_patterns)]
8265 pub fn into_all_children_present(self) -> Option<(BufferCollectionTokenGroupControlHandle)> {
8266 if let BufferCollectionTokenGroupRequest::AllChildrenPresent { control_handle } = self {
8267 Some((control_handle))
8268 } else {
8269 None
8270 }
8271 }
8272
8273 /// Name of the method defined in FIDL
8274 pub fn method_name(&self) -> &'static str {
8275 match *self {
8276 BufferCollectionTokenGroupRequest::Sync { .. } => "sync",
8277 BufferCollectionTokenGroupRequest::Close { .. } => "close",
8278 BufferCollectionTokenGroupRequest::SetName { .. } => "set_name",
8279 BufferCollectionTokenGroupRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
8280 BufferCollectionTokenGroupRequest::SetDebugTimeoutLogDeadline { .. } => {
8281 "set_debug_timeout_log_deadline"
8282 }
8283 BufferCollectionTokenGroupRequest::SetVerboseLogging { .. } => "set_verbose_logging",
8284 BufferCollectionTokenGroupRequest::GetNodeRef { .. } => "get_node_ref",
8285 BufferCollectionTokenGroupRequest::IsAlternateFor { .. } => "is_alternate_for",
8286 BufferCollectionTokenGroupRequest::CreateChild { .. } => "create_child",
8287 BufferCollectionTokenGroupRequest::CreateChildrenSync { .. } => "create_children_sync",
8288 BufferCollectionTokenGroupRequest::AllChildrenPresent { .. } => "all_children_present",
8289 }
8290 }
8291}
8292
8293#[derive(Debug, Clone)]
8294pub struct BufferCollectionTokenGroupControlHandle {
8295 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
8296}
8297
8298impl BufferCollectionTokenGroupControlHandle {
8299 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
8300 self.inner.shutdown_with_epitaph(status.into())
8301 }
8302}
8303
8304impl fidl::endpoints::ControlHandle for BufferCollectionTokenGroupControlHandle {
8305 fn shutdown(&self) {
8306 self.inner.shutdown()
8307 }
8308
8309 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
8310 self.inner.shutdown_with_epitaph(status)
8311 }
8312
8313 fn is_closed(&self) -> bool {
8314 self.inner.channel().is_closed()
8315 }
8316 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
8317 self.inner.channel().on_closed()
8318 }
8319
8320 #[cfg(target_os = "fuchsia")]
8321 fn signal_peer(
8322 &self,
8323 clear_mask: zx::Signals,
8324 set_mask: zx::Signals,
8325 ) -> Result<(), zx_status::Status> {
8326 use fidl::Peered;
8327 self.inner.channel().signal_peer(clear_mask, set_mask)
8328 }
8329}
8330
8331impl BufferCollectionTokenGroupControlHandle {}
8332
8333#[must_use = "FIDL methods require a response to be sent"]
8334#[derive(Debug)]
8335pub struct BufferCollectionTokenGroupSyncResponder {
8336 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8337 tx_id: u32,
8338}
8339
8340/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8341/// if the responder is dropped without sending a response, so that the client
8342/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8343impl std::ops::Drop for BufferCollectionTokenGroupSyncResponder {
8344 fn drop(&mut self) {
8345 self.control_handle.shutdown();
8346 // Safety: drops once, never accessed again
8347 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8348 }
8349}
8350
8351impl fidl::endpoints::Responder for BufferCollectionTokenGroupSyncResponder {
8352 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8353
8354 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8355 &self.control_handle
8356 }
8357
8358 fn drop_without_shutdown(mut self) {
8359 // Safety: drops once, never accessed again due to mem::forget
8360 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8361 // Prevent Drop from running (which would shut down the channel)
8362 std::mem::forget(self);
8363 }
8364}
8365
8366impl BufferCollectionTokenGroupSyncResponder {
8367 /// Sends a response to the FIDL transaction.
8368 ///
8369 /// Sets the channel to shutdown if an error occurs.
8370 pub fn send(self) -> Result<(), fidl::Error> {
8371 let _result = self.send_raw();
8372 if _result.is_err() {
8373 self.control_handle.shutdown();
8374 }
8375 self.drop_without_shutdown();
8376 _result
8377 }
8378
8379 /// Similar to "send" but does not shutdown the channel if an error occurs.
8380 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
8381 let _result = self.send_raw();
8382 self.drop_without_shutdown();
8383 _result
8384 }
8385
8386 fn send_raw(&self) -> Result<(), fidl::Error> {
8387 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
8388 (),
8389 self.tx_id,
8390 0x4577e238ae26291,
8391 fidl::encoding::DynamicFlags::empty(),
8392 )
8393 }
8394}
8395
8396#[must_use = "FIDL methods require a response to be sent"]
8397#[derive(Debug)]
8398pub struct BufferCollectionTokenGroupGetNodeRefResponder {
8399 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8400 tx_id: u32,
8401}
8402
8403/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8404/// if the responder is dropped without sending a response, so that the client
8405/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8406impl std::ops::Drop for BufferCollectionTokenGroupGetNodeRefResponder {
8407 fn drop(&mut self) {
8408 self.control_handle.shutdown();
8409 // Safety: drops once, never accessed again
8410 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8411 }
8412}
8413
8414impl fidl::endpoints::Responder for BufferCollectionTokenGroupGetNodeRefResponder {
8415 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8416
8417 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8418 &self.control_handle
8419 }
8420
8421 fn drop_without_shutdown(mut self) {
8422 // Safety: drops once, never accessed again due to mem::forget
8423 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8424 // Prevent Drop from running (which would shut down the channel)
8425 std::mem::forget(self);
8426 }
8427}
8428
8429impl BufferCollectionTokenGroupGetNodeRefResponder {
8430 /// Sends a response to the FIDL transaction.
8431 ///
8432 /// Sets the channel to shutdown if an error occurs.
8433 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8434 let _result = self.send_raw(node_ref);
8435 if _result.is_err() {
8436 self.control_handle.shutdown();
8437 }
8438 self.drop_without_shutdown();
8439 _result
8440 }
8441
8442 /// Similar to "send" but does not shutdown the channel if an error occurs.
8443 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8444 let _result = self.send_raw(node_ref);
8445 self.drop_without_shutdown();
8446 _result
8447 }
8448
8449 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
8450 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
8451 (node_ref,),
8452 self.tx_id,
8453 0x467b7c75c35c3b84,
8454 fidl::encoding::DynamicFlags::empty(),
8455 )
8456 }
8457}
8458
8459#[must_use = "FIDL methods require a response to be sent"]
8460#[derive(Debug)]
8461pub struct BufferCollectionTokenGroupIsAlternateForResponder {
8462 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8463 tx_id: u32,
8464}
8465
8466/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8467/// if the responder is dropped without sending a response, so that the client
8468/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8469impl std::ops::Drop for BufferCollectionTokenGroupIsAlternateForResponder {
8470 fn drop(&mut self) {
8471 self.control_handle.shutdown();
8472 // Safety: drops once, never accessed again
8473 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8474 }
8475}
8476
8477impl fidl::endpoints::Responder for BufferCollectionTokenGroupIsAlternateForResponder {
8478 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8479
8480 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8481 &self.control_handle
8482 }
8483
8484 fn drop_without_shutdown(mut self) {
8485 // Safety: drops once, never accessed again due to mem::forget
8486 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8487 // Prevent Drop from running (which would shut down the channel)
8488 std::mem::forget(self);
8489 }
8490}
8491
8492impl BufferCollectionTokenGroupIsAlternateForResponder {
8493 /// Sends a response to the FIDL transaction.
8494 ///
8495 /// Sets the channel to shutdown if an error occurs.
8496 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8497 let _result = self.send_raw(result);
8498 if _result.is_err() {
8499 self.control_handle.shutdown();
8500 }
8501 self.drop_without_shutdown();
8502 _result
8503 }
8504
8505 /// Similar to "send" but does not shutdown the channel if an error occurs.
8506 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8507 let _result = self.send_raw(result);
8508 self.drop_without_shutdown();
8509 _result
8510 }
8511
8512 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
8513 self.control_handle
8514 .inner
8515 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
8516 result.map(|is_alternate| (is_alternate,)),
8517 self.tx_id,
8518 0x33a2a7aff2776c07,
8519 fidl::encoding::DynamicFlags::empty(),
8520 )
8521 }
8522}
8523
8524#[must_use = "FIDL methods require a response to be sent"]
8525#[derive(Debug)]
8526pub struct BufferCollectionTokenGroupCreateChildrenSyncResponder {
8527 control_handle: std::mem::ManuallyDrop<BufferCollectionTokenGroupControlHandle>,
8528 tx_id: u32,
8529}
8530
8531/// Set the the channel to be shutdown (see [`BufferCollectionTokenGroupControlHandle::shutdown`])
8532/// if the responder is dropped without sending a response, so that the client
8533/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
8534impl std::ops::Drop for BufferCollectionTokenGroupCreateChildrenSyncResponder {
8535 fn drop(&mut self) {
8536 self.control_handle.shutdown();
8537 // Safety: drops once, never accessed again
8538 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8539 }
8540}
8541
8542impl fidl::endpoints::Responder for BufferCollectionTokenGroupCreateChildrenSyncResponder {
8543 type ControlHandle = BufferCollectionTokenGroupControlHandle;
8544
8545 fn control_handle(&self) -> &BufferCollectionTokenGroupControlHandle {
8546 &self.control_handle
8547 }
8548
8549 fn drop_without_shutdown(mut self) {
8550 // Safety: drops once, never accessed again due to mem::forget
8551 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
8552 // Prevent Drop from running (which would shut down the channel)
8553 std::mem::forget(self);
8554 }
8555}
8556
8557impl BufferCollectionTokenGroupCreateChildrenSyncResponder {
8558 /// Sends a response to the FIDL transaction.
8559 ///
8560 /// Sets the channel to shutdown if an error occurs.
8561 pub fn send(
8562 self,
8563 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8564 ) -> Result<(), fidl::Error> {
8565 let _result = self.send_raw(tokens);
8566 if _result.is_err() {
8567 self.control_handle.shutdown();
8568 }
8569 self.drop_without_shutdown();
8570 _result
8571 }
8572
8573 /// Similar to "send" but does not shutdown the channel if an error occurs.
8574 pub fn send_no_shutdown_on_err(
8575 self,
8576 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8577 ) -> Result<(), fidl::Error> {
8578 let _result = self.send_raw(tokens);
8579 self.drop_without_shutdown();
8580 _result
8581 }
8582
8583 fn send_raw(
8584 &self,
8585 mut tokens: Vec<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
8586 ) -> Result<(), fidl::Error> {
8587 self.control_handle.inner.send::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(
8588 (tokens.as_mut(),),
8589 self.tx_id,
8590 0x569dc3ca2a98f535,
8591 fidl::encoding::DynamicFlags::empty(),
8592 )
8593 }
8594}
8595
8596#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
8597pub struct NodeMarker;
8598
8599impl fidl::endpoints::ProtocolMarker for NodeMarker {
8600 type Proxy = NodeProxy;
8601 type RequestStream = NodeRequestStream;
8602 #[cfg(target_os = "fuchsia")]
8603 type SynchronousProxy = NodeSynchronousProxy;
8604
8605 const DEBUG_NAME: &'static str = "(anonymous) Node";
8606}
8607pub type NodeIsAlternateForResult = Result<bool, i32>;
8608
8609pub trait NodeProxyInterface: Send + Sync {
8610 type SyncResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
8611 fn r#sync(&self) -> Self::SyncResponseFut;
8612 fn r#close(&self) -> Result<(), fidl::Error>;
8613 fn r#set_name(&self, priority: u32, name: &str) -> Result<(), fidl::Error>;
8614 fn r#set_debug_client_info(&self, name: &str, id: u64) -> Result<(), fidl::Error>;
8615 fn r#set_debug_timeout_log_deadline(&self, deadline: i64) -> Result<(), fidl::Error>;
8616 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error>;
8617 type GetNodeRefResponseFut: std::future::Future<Output = Result<fidl::Event, fidl::Error>>
8618 + Send;
8619 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut;
8620 type IsAlternateForResponseFut: std::future::Future<Output = Result<NodeIsAlternateForResult, fidl::Error>>
8621 + Send;
8622 fn r#is_alternate_for(&self, node_ref: fidl::Event) -> Self::IsAlternateForResponseFut;
8623}
8624#[derive(Debug)]
8625#[cfg(target_os = "fuchsia")]
8626pub struct NodeSynchronousProxy {
8627 client: fidl::client::sync::Client,
8628}
8629
8630#[cfg(target_os = "fuchsia")]
8631impl fidl::endpoints::SynchronousProxy for NodeSynchronousProxy {
8632 type Proxy = NodeProxy;
8633 type Protocol = NodeMarker;
8634
8635 fn from_channel(inner: fidl::Channel) -> Self {
8636 Self::new(inner)
8637 }
8638
8639 fn into_channel(self) -> fidl::Channel {
8640 self.client.into_channel()
8641 }
8642
8643 fn as_channel(&self) -> &fidl::Channel {
8644 self.client.as_channel()
8645 }
8646}
8647
8648#[cfg(target_os = "fuchsia")]
8649impl NodeSynchronousProxy {
8650 pub fn new(channel: fidl::Channel) -> Self {
8651 Self { client: fidl::client::sync::Client::new(channel) }
8652 }
8653
8654 pub fn into_channel(self) -> fidl::Channel {
8655 self.client.into_channel()
8656 }
8657
8658 /// Waits until an event arrives and returns it. It is safe for other
8659 /// threads to make concurrent requests while waiting for an event.
8660 pub fn wait_for_event(&self, deadline: zx::MonotonicInstant) -> Result<NodeEvent, fidl::Error> {
8661 NodeEvent::decode(self.client.wait_for_event::<NodeMarker>(deadline)?)
8662 }
8663
8664 /// Ensure that previous messages, including Duplicate() messages on a
8665 /// token, collection, or group, have been received server side.
8666 ///
8667 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
8668 /// valid sysmem token risks the Sync() hanging forever. See
8669 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
8670 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
8671 /// Another way is to pass the token to BindSharedCollection(), which also
8672 /// validates the token as part of exchanging it for a BufferCollection
8673 /// channel, and BufferCollection Sync() can then be used.
8674 ///
8675 /// After a Sync(), it's then safe to send the client end of token_request
8676 /// to another participant knowing the server will recognize the token when
8677 /// it's sent into BindSharedCollection() by the other participant.
8678 ///
8679 /// Other options include waiting for each token.Duplicate() to complete
8680 /// individually (using separate call to token.Sync() after each), or
8681 /// calling Sync() on BufferCollection after the token has been turned in
8682 /// via BindSharedCollection().
8683 ///
8684 /// Another way to mitigate is to avoid calling Sync() on the token, and
8685 /// instead later deal with potential failure of BufferCollection.Sync() if
8686 /// the original token was invalid. This option can be preferable from a
8687 /// performance point of view, but requires client code to delay sending
8688 /// tokens duplicated from this token until after client code has converted
8689 /// the duplicating token to a BufferCollection and received successful
8690 /// response from BufferCollection.Sync().
8691 ///
8692 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
8693 /// When BufferCollection.Sync() isn't feasible, the caller must already
8694 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
8695 /// hang forever. See ValidateBufferCollectionToken() to check token
8696 /// validity first if the token isn't already known to be (is/was) valid.
8697 pub fn r#sync(&self, ___deadline: zx::MonotonicInstant) -> Result<(), fidl::Error> {
8698 let _response = self
8699 .client
8700 .send_query::<fidl::encoding::EmptyPayload, fidl::encoding::EmptyPayload, NodeMarker>(
8701 (),
8702 0x4577e238ae26291,
8703 fidl::encoding::DynamicFlags::empty(),
8704 ___deadline,
8705 )?;
8706 Ok(_response)
8707 }
8708
8709 /// On a BufferCollectionToken channel:
8710 ///
8711 /// Normally a participant will convert a BufferCollectionToken into a
8712 /// BufferCollection view, but a participant is also free to Close() the
8713 /// token (and then close the channel immediately or shortly later in
8714 /// response to server closing its end), which avoids causing logical buffer
8715 /// collection failure. Â Normally an unexpected token channel close will
8716 /// cause logical buffer collection failure (the only exceptions being
8717 /// certain cases involving AttachToken() or SetDispensable()).
8718 ///
8719 /// On a BufferCollection channel:
8720 ///
8721 /// By default the server handles unexpected failure of a BufferCollection
8722 /// by failing the whole logical buffer collection. Partly this is to
8723 /// expedite closing VMO handles to reclaim memory when any participant
8724 /// fails. If a participant would like to cleanly close a BufferCollection
8725 /// view without causing logical buffer collection failure, the participant
8726 /// can send Close() before closing the client end of the BufferCollection
8727 /// channel. If this is the last BufferCollection view, the logical buffer
8728 /// collection will still go away. The Close() can occur before or after
8729 /// SetConstraints(). If before SetConstraints(), the buffer collection
8730 /// won't require constraints from this node in order to allocate. If
8731 /// after SetConstraints(), the constraints are retained and aggregated
8732 /// along with any subsequent logical allocation(s), despite the lack of
8733 /// channel connection.
8734 ///
8735 /// On a BufferCollectionTokenGroup channel:
8736 ///
8737 /// By default, unexpected failure of a BufferCollectionTokenGroup will
8738 /// trigger failure of the logical BufferCollectionTokenGroup and will
8739 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
8740 /// channel without failing the logical group or propagating failure, send
8741 /// Close() before closing the channel client endpoint.
8742 ///
8743 /// If Close() occurs before AllChildrenPresent(), the logical buffer
8744 /// collection will still fail despite the Close() (because sysmem can't be
8745 /// sure whether all relevant children were created, so it's ambiguous
8746 /// whether all relevant constraints will be provided to sysmem). If
8747 /// Close() occurs after AllChildrenPresent(), the children and all their
8748 /// constraints remain intact (just as they would if the
8749 /// BufferCollectionTokenGroup channel had remained open), and the close
8750 /// doesn't trigger or propagate failure.
8751 pub fn r#close(&self) -> Result<(), fidl::Error> {
8752 self.client.send::<fidl::encoding::EmptyPayload>(
8753 (),
8754 0x5b1d7a4f5681fca7,
8755 fidl::encoding::DynamicFlags::empty(),
8756 )
8757 }
8758
8759 /// Set a name for VMOs in this buffer collection. The name may be truncated
8760 /// shorter. The name only affects VMOs allocated after it's set - this call
8761 /// does not rename existing VMOs. If multiple clients set different names
8762 /// then the larger priority value will win.
8763 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
8764 self.client.send::<NodeSetNameRequest>(
8765 (priority, name),
8766 0x77a41bb6217e2443,
8767 fidl::encoding::DynamicFlags::empty(),
8768 )
8769 }
8770
8771 /// Set information about the current client that can be used by sysmem to
8772 /// help debug leaking memory and hangs waiting for constraints. |name| can
8773 /// be an arbitrary string, but the current process name (see
8774 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
8775 /// arbitrary id, but the current process ID (see
8776 /// fsl::GetCurrentProcessKoid()) is a good default.
8777 ///
8778 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
8779 /// indicate which client is closing their channel first, leading to
8780 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
8781 /// over, but if happening earlier than expected, the
8782 /// client-channel-specific name can help diagnose where the failure is
8783 /// first coming from, from sysmem's point of view).
8784 ///
8785 /// By default (unless overriden by this message or using
8786 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
8787 /// parent Node at the time the child Node is created. While this can be
8788 /// better than nothing, it's often better for each participant to use
8789 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
8790 /// info directly relevant to the current client. Also, SetVerboseLogging()
8791 /// can be used to help disambiguate if a Node is suspected of having info
8792 /// that was copied from its parent.
8793 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
8794 self.client.send::<NodeSetDebugClientInfoRequest>(
8795 (name, id),
8796 0x7275759070eb5ee2,
8797 fidl::encoding::DynamicFlags::empty(),
8798 )
8799 }
8800
8801 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
8802 /// after creating a collection. Clients can call this method to change
8803 /// when the log is printed. If multiple client set the deadline, it's
8804 /// unspecified which deadline will take effect.
8805 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
8806 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
8807 (deadline,),
8808 0x46d38f4772638867,
8809 fidl::encoding::DynamicFlags::empty(),
8810 )
8811 }
8812
8813 /// Verbose logging includes constraints set via SetConstraints() from each
8814 /// client along with info set via SetDebugClientInfo() and the structure of
8815 /// the tree of Node(s).
8816 ///
8817 /// Normally sysmem prints only a single line complaint when aggregation
8818 /// fails, with just the specific detailed reason that aggregation failed,
8819 /// with minimal context. While this is often enough to diagnose a problem
8820 /// if only a small change was made and the system had been working before
8821 /// the small change, it's often not particularly helpful for getting a new
8822 /// buffer collection to work for the first time. Especially with more
8823 /// complex trees of nodes, involving things like AttachToken(),
8824 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
8825 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
8826 /// looks like and why it's failing a logical allocation, or why a tree or
8827 /// sub-tree is failing sooner than expected.
8828 ///
8829 /// The intent of the extra logging is to be acceptable from a performance
8830 /// point of view, if only enabled on a low number of buffer collections.
8831 /// If we're not tracking down a bug, we shouldn't send this message.
8832 ///
8833 /// If too many participants leave verbose logging enabled, we may end up
8834 /// needing to require that system-wide sysmem verbose logging be permitted
8835 /// via some other setting, to avoid sysmem spamming the log too much due to
8836 /// this message.
8837 ///
8838 /// This may be a NOP for some nodes due to intentional policy associated
8839 /// with the node, if we don't trust a node enough to let it turn on verbose
8840 /// logging.
8841 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
8842 self.client.send::<fidl::encoding::EmptyPayload>(
8843 (),
8844 0x6bfbe2cf1701d288,
8845 fidl::encoding::DynamicFlags::empty(),
8846 )
8847 }
8848
8849 /// This gets an event handle that can be used as a parameter to
8850 /// IsAlternateFor() called on any Node. The client will not be granted the
8851 /// right to signal this event, as this handle should only be used as proof
8852 /// that the client obtained this handle from this Node.
8853 ///
8854 /// Because this is a get not a set, no Sync() is needed between the
8855 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
8856 /// potentially being on different channels.
8857 ///
8858 /// See also IsAlternateFor().
8859 pub fn r#get_node_ref(
8860 &self,
8861 ___deadline: zx::MonotonicInstant,
8862 ) -> Result<fidl::Event, fidl::Error> {
8863 let _response = self
8864 .client
8865 .send_query::<fidl::encoding::EmptyPayload, NodeGetNodeRefResponse, NodeMarker>(
8866 (),
8867 0x467b7c75c35c3b84,
8868 fidl::encoding::DynamicFlags::empty(),
8869 ___deadline,
8870 )?;
8871 Ok(_response.node_ref)
8872 }
8873
8874 /// This checks whether the calling node is in a subtree rooted at a
8875 /// different child token of a common parent BufferCollectionTokenGroup, in
8876 /// relation to the passed-in node_ref.
8877 ///
8878 /// This call is for assisting with admission control de-duplication, and
8879 /// with debugging.
8880 ///
8881 /// The node_ref must be obtained using GetNodeRef() of a
8882 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
8883 ///
8884 /// The node_ref can be a duplicated handle; it's not necessary to call
8885 /// GetNodeRef() for every call to IsAlternateFor().
8886 ///
8887 /// If a calling token may not actually be a valid token at all due to
8888 /// a potentially hostile/untrusted provider of the token, call
8889 /// ValidateBufferCollectionToken() first instead of potentially getting
8890 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
8891 /// token not being a real token (not really talking to sysmem). Another
8892 /// option is to call BindSharedCollection with this token first which also
8893 /// validates the token along with converting it to a BufferCollection, then
8894 /// call BufferCollection IsAlternateFor().
8895 ///
8896 /// error values:
8897 ///
8898 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
8899 /// buffer collection as the calling Node. Before logical allocation and
8900 /// within the same logical allocation sub-tree, this essentially means that
8901 /// the node_ref was never part of this logical buffer collection, since
8902 /// before logical allocation all node_refs that come into existence remain
8903 /// in existence at least until logical allocation (including Node(s) that
8904 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
8905 /// to be returned, this Node's channel needs to still be connected server
8906 /// side, which won't be the case if the whole logical allocation has
8907 /// failed. After logical allocation or in a different logical allocation
8908 /// sub-tree there are additional potential reasons for this error. For
8909 /// example a different logical allocation (separated from this Node(s)
8910 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
8911 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
8912 /// exist and may select a different child sub-tree than the sub-tree the
8913 /// node_ref is in causing deletion of the node_ref Node. The only time
8914 /// sysmem keeps a Node around after that Node has no corresponding channel
8915 /// is when Close() is used and the Node's sub-tree has not yet failed.
8916 /// Another reason for this error is if the node_ref is an eventpair handle
8917 /// with sufficient rights, but isn't actually a real node_ref obtained from
8918 /// GetNodeRef().
8919 ///
8920 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
8921 /// eventpair handle, or doesn't have the needed rights expected on a real
8922 /// node_ref.
8923 ///
8924 /// No other failing status codes are returned by this call. However,
8925 /// sysmem may add additional codes in future, so the client should have
8926 /// sensible default handling for any failing status code.
8927 ///
8928 /// On success, is_alternate has the following meaning:
8929 /// * true - The first parent node in common between the calling node and
8930 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
8931 /// the calling Node and the node_ref Node will _not_ have both their
8932 /// constraints apply - rather sysmem will choose one or the other of
8933 /// the constraints - never both. This is because only one child of
8934 /// a BufferCollectionTokenGroup is selected during logical allocation,
8935 /// with only that one child's sub-tree contributing to constraints
8936 /// aggregation.
8937 /// * false - The first parent node in common between the calling Node and
8938 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
8939 /// this means the first parent node in common is a
8940 /// BufferCollectionToken or BufferCollection (regardless of not
8941 /// Close()ed or Close()ed). This means that the calling Node and the
8942 /// node_ref Node _may_ have both their constraints apply during
8943 /// constraints aggregation of the logical allocation, if both Node(s)
8944 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
8945 /// In this case, there is no BufferCollectionTokenGroup that will
8946 /// directly prevent the two Node(s) from both being selected and their
8947 /// constraints both aggregated, but even when false, one or both
8948 /// Node(s) may still be eliminated from consideration if one or both
8949 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
8950 /// which selects a child sub-tree other than the sub-tree containing
8951 /// the calling Node or node_ref Node.
8952 pub fn r#is_alternate_for(
8953 &self,
8954 mut node_ref: fidl::Event,
8955 ___deadline: zx::MonotonicInstant,
8956 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
8957 let _response = self.client.send_query::<
8958 NodeIsAlternateForRequest,
8959 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
8960 NodeMarker,
8961 >(
8962 (node_ref,),
8963 0x33a2a7aff2776c07,
8964 fidl::encoding::DynamicFlags::empty(),
8965 ___deadline,
8966 )?;
8967 Ok(_response.map(|x| x.is_alternate))
8968 }
8969}
8970
8971#[cfg(target_os = "fuchsia")]
8972impl From<NodeSynchronousProxy> for zx::NullableHandle {
8973 fn from(value: NodeSynchronousProxy) -> Self {
8974 value.into_channel().into()
8975 }
8976}
8977
8978#[cfg(target_os = "fuchsia")]
8979impl From<fidl::Channel> for NodeSynchronousProxy {
8980 fn from(value: fidl::Channel) -> Self {
8981 Self::new(value)
8982 }
8983}
8984
8985#[cfg(target_os = "fuchsia")]
8986impl fidl::endpoints::FromClient for NodeSynchronousProxy {
8987 type Protocol = NodeMarker;
8988
8989 fn from_client(value: fidl::endpoints::ClientEnd<NodeMarker>) -> Self {
8990 Self::new(value.into_channel())
8991 }
8992}
8993
8994#[derive(Debug, Clone)]
8995pub struct NodeProxy {
8996 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
8997}
8998
8999impl fidl::endpoints::Proxy for NodeProxy {
9000 type Protocol = NodeMarker;
9001
9002 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
9003 Self::new(inner)
9004 }
9005
9006 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
9007 self.client.into_channel().map_err(|client| Self { client })
9008 }
9009
9010 fn as_channel(&self) -> &::fidl::AsyncChannel {
9011 self.client.as_channel()
9012 }
9013}
9014
9015impl NodeProxy {
9016 /// Create a new Proxy for fuchsia.sysmem/Node.
9017 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
9018 let protocol_name = <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
9019 Self { client: fidl::client::Client::new(channel, protocol_name) }
9020 }
9021
9022 /// Get a Stream of events from the remote end of the protocol.
9023 ///
9024 /// # Panics
9025 ///
9026 /// Panics if the event stream was already taken.
9027 pub fn take_event_stream(&self) -> NodeEventStream {
9028 NodeEventStream { event_receiver: self.client.take_event_receiver() }
9029 }
9030
9031 /// Ensure that previous messages, including Duplicate() messages on a
9032 /// token, collection, or group, have been received server side.
9033 ///
9034 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
9035 /// valid sysmem token risks the Sync() hanging forever. See
9036 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
9037 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
9038 /// Another way is to pass the token to BindSharedCollection(), which also
9039 /// validates the token as part of exchanging it for a BufferCollection
9040 /// channel, and BufferCollection Sync() can then be used.
9041 ///
9042 /// After a Sync(), it's then safe to send the client end of token_request
9043 /// to another participant knowing the server will recognize the token when
9044 /// it's sent into BindSharedCollection() by the other participant.
9045 ///
9046 /// Other options include waiting for each token.Duplicate() to complete
9047 /// individually (using separate call to token.Sync() after each), or
9048 /// calling Sync() on BufferCollection after the token has been turned in
9049 /// via BindSharedCollection().
9050 ///
9051 /// Another way to mitigate is to avoid calling Sync() on the token, and
9052 /// instead later deal with potential failure of BufferCollection.Sync() if
9053 /// the original token was invalid. This option can be preferable from a
9054 /// performance point of view, but requires client code to delay sending
9055 /// tokens duplicated from this token until after client code has converted
9056 /// the duplicating token to a BufferCollection and received successful
9057 /// response from BufferCollection.Sync().
9058 ///
9059 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
9060 /// When BufferCollection.Sync() isn't feasible, the caller must already
9061 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
9062 /// hang forever. See ValidateBufferCollectionToken() to check token
9063 /// validity first if the token isn't already known to be (is/was) valid.
9064 pub fn r#sync(
9065 &self,
9066 ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
9067 NodeProxyInterface::r#sync(self)
9068 }
9069
9070 /// On a BufferCollectionToken channel:
9071 ///
9072 /// Normally a participant will convert a BufferCollectionToken into a
9073 /// BufferCollection view, but a participant is also free to Close() the
9074 /// token (and then close the channel immediately or shortly later in
9075 /// response to server closing its end), which avoids causing logical buffer
9076 /// collection failure. Â Normally an unexpected token channel close will
9077 /// cause logical buffer collection failure (the only exceptions being
9078 /// certain cases involving AttachToken() or SetDispensable()).
9079 ///
9080 /// On a BufferCollection channel:
9081 ///
9082 /// By default the server handles unexpected failure of a BufferCollection
9083 /// by failing the whole logical buffer collection. Partly this is to
9084 /// expedite closing VMO handles to reclaim memory when any participant
9085 /// fails. If a participant would like to cleanly close a BufferCollection
9086 /// view without causing logical buffer collection failure, the participant
9087 /// can send Close() before closing the client end of the BufferCollection
9088 /// channel. If this is the last BufferCollection view, the logical buffer
9089 /// collection will still go away. The Close() can occur before or after
9090 /// SetConstraints(). If before SetConstraints(), the buffer collection
9091 /// won't require constraints from this node in order to allocate. If
9092 /// after SetConstraints(), the constraints are retained and aggregated
9093 /// along with any subsequent logical allocation(s), despite the lack of
9094 /// channel connection.
9095 ///
9096 /// On a BufferCollectionTokenGroup channel:
9097 ///
9098 /// By default, unexpected failure of a BufferCollectionTokenGroup will
9099 /// trigger failure of the logical BufferCollectionTokenGroup and will
9100 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
9101 /// channel without failing the logical group or propagating failure, send
9102 /// Close() before closing the channel client endpoint.
9103 ///
9104 /// If Close() occurs before AllChildrenPresent(), the logical buffer
9105 /// collection will still fail despite the Close() (because sysmem can't be
9106 /// sure whether all relevant children were created, so it's ambiguous
9107 /// whether all relevant constraints will be provided to sysmem). If
9108 /// Close() occurs after AllChildrenPresent(), the children and all their
9109 /// constraints remain intact (just as they would if the
9110 /// BufferCollectionTokenGroup channel had remained open), and the close
9111 /// doesn't trigger or propagate failure.
9112 pub fn r#close(&self) -> Result<(), fidl::Error> {
9113 NodeProxyInterface::r#close(self)
9114 }
9115
9116 /// Set a name for VMOs in this buffer collection. The name may be truncated
9117 /// shorter. The name only affects VMOs allocated after it's set - this call
9118 /// does not rename existing VMOs. If multiple clients set different names
9119 /// then the larger priority value will win.
9120 pub fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
9121 NodeProxyInterface::r#set_name(self, priority, name)
9122 }
9123
9124 /// Set information about the current client that can be used by sysmem to
9125 /// help debug leaking memory and hangs waiting for constraints. |name| can
9126 /// be an arbitrary string, but the current process name (see
9127 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
9128 /// arbitrary id, but the current process ID (see
9129 /// fsl::GetCurrentProcessKoid()) is a good default.
9130 ///
9131 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
9132 /// indicate which client is closing their channel first, leading to
9133 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
9134 /// over, but if happening earlier than expected, the
9135 /// client-channel-specific name can help diagnose where the failure is
9136 /// first coming from, from sysmem's point of view).
9137 ///
9138 /// By default (unless overriden by this message or using
9139 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
9140 /// parent Node at the time the child Node is created. While this can be
9141 /// better than nothing, it's often better for each participant to use
9142 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
9143 /// info directly relevant to the current client. Also, SetVerboseLogging()
9144 /// can be used to help disambiguate if a Node is suspected of having info
9145 /// that was copied from its parent.
9146 pub fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
9147 NodeProxyInterface::r#set_debug_client_info(self, name, id)
9148 }
9149
9150 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
9151 /// after creating a collection. Clients can call this method to change
9152 /// when the log is printed. If multiple client set the deadline, it's
9153 /// unspecified which deadline will take effect.
9154 pub fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
9155 NodeProxyInterface::r#set_debug_timeout_log_deadline(self, deadline)
9156 }
9157
9158 /// Verbose logging includes constraints set via SetConstraints() from each
9159 /// client along with info set via SetDebugClientInfo() and the structure of
9160 /// the tree of Node(s).
9161 ///
9162 /// Normally sysmem prints only a single line complaint when aggregation
9163 /// fails, with just the specific detailed reason that aggregation failed,
9164 /// with minimal context. While this is often enough to diagnose a problem
9165 /// if only a small change was made and the system had been working before
9166 /// the small change, it's often not particularly helpful for getting a new
9167 /// buffer collection to work for the first time. Especially with more
9168 /// complex trees of nodes, involving things like AttachToken(),
9169 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
9170 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
9171 /// looks like and why it's failing a logical allocation, or why a tree or
9172 /// sub-tree is failing sooner than expected.
9173 ///
9174 /// The intent of the extra logging is to be acceptable from a performance
9175 /// point of view, if only enabled on a low number of buffer collections.
9176 /// If we're not tracking down a bug, we shouldn't send this message.
9177 ///
9178 /// If too many participants leave verbose logging enabled, we may end up
9179 /// needing to require that system-wide sysmem verbose logging be permitted
9180 /// via some other setting, to avoid sysmem spamming the log too much due to
9181 /// this message.
9182 ///
9183 /// This may be a NOP for some nodes due to intentional policy associated
9184 /// with the node, if we don't trust a node enough to let it turn on verbose
9185 /// logging.
9186 pub fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
9187 NodeProxyInterface::r#set_verbose_logging(self)
9188 }
9189
9190 /// This gets an event handle that can be used as a parameter to
9191 /// IsAlternateFor() called on any Node. The client will not be granted the
9192 /// right to signal this event, as this handle should only be used as proof
9193 /// that the client obtained this handle from this Node.
9194 ///
9195 /// Because this is a get not a set, no Sync() is needed between the
9196 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
9197 /// potentially being on different channels.
9198 ///
9199 /// See also IsAlternateFor().
9200 pub fn r#get_node_ref(
9201 &self,
9202 ) -> fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>
9203 {
9204 NodeProxyInterface::r#get_node_ref(self)
9205 }
9206
9207 /// This checks whether the calling node is in a subtree rooted at a
9208 /// different child token of a common parent BufferCollectionTokenGroup, in
9209 /// relation to the passed-in node_ref.
9210 ///
9211 /// This call is for assisting with admission control de-duplication, and
9212 /// with debugging.
9213 ///
9214 /// The node_ref must be obtained using GetNodeRef() of a
9215 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
9216 ///
9217 /// The node_ref can be a duplicated handle; it's not necessary to call
9218 /// GetNodeRef() for every call to IsAlternateFor().
9219 ///
9220 /// If a calling token may not actually be a valid token at all due to
9221 /// a potentially hostile/untrusted provider of the token, call
9222 /// ValidateBufferCollectionToken() first instead of potentially getting
9223 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
9224 /// token not being a real token (not really talking to sysmem). Another
9225 /// option is to call BindSharedCollection with this token first which also
9226 /// validates the token along with converting it to a BufferCollection, then
9227 /// call BufferCollection IsAlternateFor().
9228 ///
9229 /// error values:
9230 ///
9231 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
9232 /// buffer collection as the calling Node. Before logical allocation and
9233 /// within the same logical allocation sub-tree, this essentially means that
9234 /// the node_ref was never part of this logical buffer collection, since
9235 /// before logical allocation all node_refs that come into existence remain
9236 /// in existence at least until logical allocation (including Node(s) that
9237 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
9238 /// to be returned, this Node's channel needs to still be connected server
9239 /// side, which won't be the case if the whole logical allocation has
9240 /// failed. After logical allocation or in a different logical allocation
9241 /// sub-tree there are additional potential reasons for this error. For
9242 /// example a different logical allocation (separated from this Node(s)
9243 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
9244 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
9245 /// exist and may select a different child sub-tree than the sub-tree the
9246 /// node_ref is in causing deletion of the node_ref Node. The only time
9247 /// sysmem keeps a Node around after that Node has no corresponding channel
9248 /// is when Close() is used and the Node's sub-tree has not yet failed.
9249 /// Another reason for this error is if the node_ref is an eventpair handle
9250 /// with sufficient rights, but isn't actually a real node_ref obtained from
9251 /// GetNodeRef().
9252 ///
9253 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
9254 /// eventpair handle, or doesn't have the needed rights expected on a real
9255 /// node_ref.
9256 ///
9257 /// No other failing status codes are returned by this call. However,
9258 /// sysmem may add additional codes in future, so the client should have
9259 /// sensible default handling for any failing status code.
9260 ///
9261 /// On success, is_alternate has the following meaning:
9262 /// * true - The first parent node in common between the calling node and
9263 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
9264 /// the calling Node and the node_ref Node will _not_ have both their
9265 /// constraints apply - rather sysmem will choose one or the other of
9266 /// the constraints - never both. This is because only one child of
9267 /// a BufferCollectionTokenGroup is selected during logical allocation,
9268 /// with only that one child's sub-tree contributing to constraints
9269 /// aggregation.
9270 /// * false - The first parent node in common between the calling Node and
9271 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
9272 /// this means the first parent node in common is a
9273 /// BufferCollectionToken or BufferCollection (regardless of not
9274 /// Close()ed or Close()ed). This means that the calling Node and the
9275 /// node_ref Node _may_ have both their constraints apply during
9276 /// constraints aggregation of the logical allocation, if both Node(s)
9277 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
9278 /// In this case, there is no BufferCollectionTokenGroup that will
9279 /// directly prevent the two Node(s) from both being selected and their
9280 /// constraints both aggregated, but even when false, one or both
9281 /// Node(s) may still be eliminated from consideration if one or both
9282 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
9283 /// which selects a child sub-tree other than the sub-tree containing
9284 /// the calling Node or node_ref Node.
9285 pub fn r#is_alternate_for(
9286 &self,
9287 mut node_ref: fidl::Event,
9288 ) -> fidl::client::QueryResponseFut<
9289 NodeIsAlternateForResult,
9290 fidl::encoding::DefaultFuchsiaResourceDialect,
9291 > {
9292 NodeProxyInterface::r#is_alternate_for(self, node_ref)
9293 }
9294}
9295
9296impl NodeProxyInterface for NodeProxy {
9297 type SyncResponseFut =
9298 fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
9299 fn r#sync(&self) -> Self::SyncResponseFut {
9300 fn _decode(
9301 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9302 ) -> Result<(), fidl::Error> {
9303 let _response = fidl::client::decode_transaction_body::<
9304 fidl::encoding::EmptyPayload,
9305 fidl::encoding::DefaultFuchsiaResourceDialect,
9306 0x4577e238ae26291,
9307 >(_buf?)?;
9308 Ok(_response)
9309 }
9310 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ()>(
9311 (),
9312 0x4577e238ae26291,
9313 fidl::encoding::DynamicFlags::empty(),
9314 _decode,
9315 )
9316 }
9317
9318 fn r#close(&self) -> Result<(), fidl::Error> {
9319 self.client.send::<fidl::encoding::EmptyPayload>(
9320 (),
9321 0x5b1d7a4f5681fca7,
9322 fidl::encoding::DynamicFlags::empty(),
9323 )
9324 }
9325
9326 fn r#set_name(&self, mut priority: u32, mut name: &str) -> Result<(), fidl::Error> {
9327 self.client.send::<NodeSetNameRequest>(
9328 (priority, name),
9329 0x77a41bb6217e2443,
9330 fidl::encoding::DynamicFlags::empty(),
9331 )
9332 }
9333
9334 fn r#set_debug_client_info(&self, mut name: &str, mut id: u64) -> Result<(), fidl::Error> {
9335 self.client.send::<NodeSetDebugClientInfoRequest>(
9336 (name, id),
9337 0x7275759070eb5ee2,
9338 fidl::encoding::DynamicFlags::empty(),
9339 )
9340 }
9341
9342 fn r#set_debug_timeout_log_deadline(&self, mut deadline: i64) -> Result<(), fidl::Error> {
9343 self.client.send::<NodeSetDebugTimeoutLogDeadlineRequest>(
9344 (deadline,),
9345 0x46d38f4772638867,
9346 fidl::encoding::DynamicFlags::empty(),
9347 )
9348 }
9349
9350 fn r#set_verbose_logging(&self) -> Result<(), fidl::Error> {
9351 self.client.send::<fidl::encoding::EmptyPayload>(
9352 (),
9353 0x6bfbe2cf1701d288,
9354 fidl::encoding::DynamicFlags::empty(),
9355 )
9356 }
9357
9358 type GetNodeRefResponseFut =
9359 fidl::client::QueryResponseFut<fidl::Event, fidl::encoding::DefaultFuchsiaResourceDialect>;
9360 fn r#get_node_ref(&self) -> Self::GetNodeRefResponseFut {
9361 fn _decode(
9362 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9363 ) -> Result<fidl::Event, fidl::Error> {
9364 let _response = fidl::client::decode_transaction_body::<
9365 NodeGetNodeRefResponse,
9366 fidl::encoding::DefaultFuchsiaResourceDialect,
9367 0x467b7c75c35c3b84,
9368 >(_buf?)?;
9369 Ok(_response.node_ref)
9370 }
9371 self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, fidl::Event>(
9372 (),
9373 0x467b7c75c35c3b84,
9374 fidl::encoding::DynamicFlags::empty(),
9375 _decode,
9376 )
9377 }
9378
9379 type IsAlternateForResponseFut = fidl::client::QueryResponseFut<
9380 NodeIsAlternateForResult,
9381 fidl::encoding::DefaultFuchsiaResourceDialect,
9382 >;
9383 fn r#is_alternate_for(&self, mut node_ref: fidl::Event) -> Self::IsAlternateForResponseFut {
9384 fn _decode(
9385 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
9386 ) -> Result<NodeIsAlternateForResult, fidl::Error> {
9387 let _response = fidl::client::decode_transaction_body::<
9388 fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>,
9389 fidl::encoding::DefaultFuchsiaResourceDialect,
9390 0x33a2a7aff2776c07,
9391 >(_buf?)?;
9392 Ok(_response.map(|x| x.is_alternate))
9393 }
9394 self.client.send_query_and_decode::<NodeIsAlternateForRequest, NodeIsAlternateForResult>(
9395 (node_ref,),
9396 0x33a2a7aff2776c07,
9397 fidl::encoding::DynamicFlags::empty(),
9398 _decode,
9399 )
9400 }
9401}
9402
9403pub struct NodeEventStream {
9404 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
9405}
9406
9407impl std::marker::Unpin for NodeEventStream {}
9408
9409impl futures::stream::FusedStream for NodeEventStream {
9410 fn is_terminated(&self) -> bool {
9411 self.event_receiver.is_terminated()
9412 }
9413}
9414
9415impl futures::Stream for NodeEventStream {
9416 type Item = Result<NodeEvent, fidl::Error>;
9417
9418 fn poll_next(
9419 mut self: std::pin::Pin<&mut Self>,
9420 cx: &mut std::task::Context<'_>,
9421 ) -> std::task::Poll<Option<Self::Item>> {
9422 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
9423 &mut self.event_receiver,
9424 cx
9425 )?) {
9426 Some(buf) => std::task::Poll::Ready(Some(NodeEvent::decode(buf))),
9427 None => std::task::Poll::Ready(None),
9428 }
9429 }
9430}
9431
9432#[derive(Debug)]
9433pub enum NodeEvent {}
9434
9435impl NodeEvent {
9436 /// Decodes a message buffer as a [`NodeEvent`].
9437 fn decode(
9438 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
9439 ) -> Result<NodeEvent, fidl::Error> {
9440 let (bytes, _handles) = buf.split_mut();
9441 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
9442 debug_assert_eq!(tx_header.tx_id, 0);
9443 match tx_header.ordinal {
9444 _ => Err(fidl::Error::UnknownOrdinal {
9445 ordinal: tx_header.ordinal,
9446 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
9447 }),
9448 }
9449 }
9450}
9451
9452/// A Stream of incoming requests for fuchsia.sysmem/Node.
9453pub struct NodeRequestStream {
9454 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9455 is_terminated: bool,
9456}
9457
9458impl std::marker::Unpin for NodeRequestStream {}
9459
9460impl futures::stream::FusedStream for NodeRequestStream {
9461 fn is_terminated(&self) -> bool {
9462 self.is_terminated
9463 }
9464}
9465
9466impl fidl::endpoints::RequestStream for NodeRequestStream {
9467 type Protocol = NodeMarker;
9468 type ControlHandle = NodeControlHandle;
9469
9470 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
9471 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
9472 }
9473
9474 fn control_handle(&self) -> Self::ControlHandle {
9475 NodeControlHandle { inner: self.inner.clone() }
9476 }
9477
9478 fn into_inner(
9479 self,
9480 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
9481 {
9482 (self.inner, self.is_terminated)
9483 }
9484
9485 fn from_inner(
9486 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9487 is_terminated: bool,
9488 ) -> Self {
9489 Self { inner, is_terminated }
9490 }
9491}
9492
9493impl futures::Stream for NodeRequestStream {
9494 type Item = Result<NodeRequest, fidl::Error>;
9495
9496 fn poll_next(
9497 mut self: std::pin::Pin<&mut Self>,
9498 cx: &mut std::task::Context<'_>,
9499 ) -> std::task::Poll<Option<Self::Item>> {
9500 let this = &mut *self;
9501 if this.inner.check_shutdown(cx) {
9502 this.is_terminated = true;
9503 return std::task::Poll::Ready(None);
9504 }
9505 if this.is_terminated {
9506 panic!("polled NodeRequestStream after completion");
9507 }
9508 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
9509 |bytes, handles| {
9510 match this.inner.channel().read_etc(cx, bytes, handles) {
9511 std::task::Poll::Ready(Ok(())) => {}
9512 std::task::Poll::Pending => return std::task::Poll::Pending,
9513 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
9514 this.is_terminated = true;
9515 return std::task::Poll::Ready(None);
9516 }
9517 std::task::Poll::Ready(Err(e)) => {
9518 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
9519 e.into(),
9520 ))));
9521 }
9522 }
9523
9524 // A message has been received from the channel
9525 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
9526
9527 std::task::Poll::Ready(Some(match header.ordinal {
9528 0x4577e238ae26291 => {
9529 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9530 let mut req = fidl::new_empty!(
9531 fidl::encoding::EmptyPayload,
9532 fidl::encoding::DefaultFuchsiaResourceDialect
9533 );
9534 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9535 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9536 Ok(NodeRequest::Sync {
9537 responder: NodeSyncResponder {
9538 control_handle: std::mem::ManuallyDrop::new(control_handle),
9539 tx_id: header.tx_id,
9540 },
9541 })
9542 }
9543 0x5b1d7a4f5681fca7 => {
9544 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9545 let mut req = fidl::new_empty!(
9546 fidl::encoding::EmptyPayload,
9547 fidl::encoding::DefaultFuchsiaResourceDialect
9548 );
9549 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9550 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9551 Ok(NodeRequest::Close { control_handle })
9552 }
9553 0x77a41bb6217e2443 => {
9554 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9555 let mut req = fidl::new_empty!(
9556 NodeSetNameRequest,
9557 fidl::encoding::DefaultFuchsiaResourceDialect
9558 );
9559 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetNameRequest>(&header, _body_bytes, handles, &mut req)?;
9560 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9561 Ok(NodeRequest::SetName {
9562 priority: req.priority,
9563 name: req.name,
9564
9565 control_handle,
9566 })
9567 }
9568 0x7275759070eb5ee2 => {
9569 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9570 let mut req = fidl::new_empty!(
9571 NodeSetDebugClientInfoRequest,
9572 fidl::encoding::DefaultFuchsiaResourceDialect
9573 );
9574 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugClientInfoRequest>(&header, _body_bytes, handles, &mut req)?;
9575 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9576 Ok(NodeRequest::SetDebugClientInfo {
9577 name: req.name,
9578 id: req.id,
9579
9580 control_handle,
9581 })
9582 }
9583 0x46d38f4772638867 => {
9584 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9585 let mut req = fidl::new_empty!(
9586 NodeSetDebugTimeoutLogDeadlineRequest,
9587 fidl::encoding::DefaultFuchsiaResourceDialect
9588 );
9589 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeSetDebugTimeoutLogDeadlineRequest>(&header, _body_bytes, handles, &mut req)?;
9590 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9591 Ok(NodeRequest::SetDebugTimeoutLogDeadline {
9592 deadline: req.deadline,
9593
9594 control_handle,
9595 })
9596 }
9597 0x6bfbe2cf1701d288 => {
9598 header.validate_request_tx_id(fidl::MethodType::OneWay)?;
9599 let mut req = fidl::new_empty!(
9600 fidl::encoding::EmptyPayload,
9601 fidl::encoding::DefaultFuchsiaResourceDialect
9602 );
9603 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9604 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9605 Ok(NodeRequest::SetVerboseLogging { control_handle })
9606 }
9607 0x467b7c75c35c3b84 => {
9608 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9609 let mut req = fidl::new_empty!(
9610 fidl::encoding::EmptyPayload,
9611 fidl::encoding::DefaultFuchsiaResourceDialect
9612 );
9613 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
9614 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9615 Ok(NodeRequest::GetNodeRef {
9616 responder: NodeGetNodeRefResponder {
9617 control_handle: std::mem::ManuallyDrop::new(control_handle),
9618 tx_id: header.tx_id,
9619 },
9620 })
9621 }
9622 0x33a2a7aff2776c07 => {
9623 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
9624 let mut req = fidl::new_empty!(
9625 NodeIsAlternateForRequest,
9626 fidl::encoding::DefaultFuchsiaResourceDialect
9627 );
9628 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<NodeIsAlternateForRequest>(&header, _body_bytes, handles, &mut req)?;
9629 let control_handle = NodeControlHandle { inner: this.inner.clone() };
9630 Ok(NodeRequest::IsAlternateFor {
9631 node_ref: req.node_ref,
9632
9633 responder: NodeIsAlternateForResponder {
9634 control_handle: std::mem::ManuallyDrop::new(control_handle),
9635 tx_id: header.tx_id,
9636 },
9637 })
9638 }
9639 _ => Err(fidl::Error::UnknownOrdinal {
9640 ordinal: header.ordinal,
9641 protocol_name: <NodeMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
9642 }),
9643 }))
9644 },
9645 )
9646 }
9647}
9648
9649#[derive(Debug)]
9650pub enum NodeRequest {
9651 /// Ensure that previous messages, including Duplicate() messages on a
9652 /// token, collection, or group, have been received server side.
9653 ///
9654 /// Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a
9655 /// valid sysmem token risks the Sync() hanging forever. See
9656 /// ValidateBufferCollectionToken() for one way to mitigate the possibility
9657 /// of a hostile/fake BufferCollectionToken at the cost of one round trip.
9658 /// Another way is to pass the token to BindSharedCollection(), which also
9659 /// validates the token as part of exchanging it for a BufferCollection
9660 /// channel, and BufferCollection Sync() can then be used.
9661 ///
9662 /// After a Sync(), it's then safe to send the client end of token_request
9663 /// to another participant knowing the server will recognize the token when
9664 /// it's sent into BindSharedCollection() by the other participant.
9665 ///
9666 /// Other options include waiting for each token.Duplicate() to complete
9667 /// individually (using separate call to token.Sync() after each), or
9668 /// calling Sync() on BufferCollection after the token has been turned in
9669 /// via BindSharedCollection().
9670 ///
9671 /// Another way to mitigate is to avoid calling Sync() on the token, and
9672 /// instead later deal with potential failure of BufferCollection.Sync() if
9673 /// the original token was invalid. This option can be preferable from a
9674 /// performance point of view, but requires client code to delay sending
9675 /// tokens duplicated from this token until after client code has converted
9676 /// the duplicating token to a BufferCollection and received successful
9677 /// response from BufferCollection.Sync().
9678 ///
9679 /// Prefer using BufferCollection.Sync() instead, when feasible (see above).
9680 /// When BufferCollection.Sync() isn't feasible, the caller must already
9681 /// know that this token is/was valid, or BufferCollectionToken.Sync() may
9682 /// hang forever. See ValidateBufferCollectionToken() to check token
9683 /// validity first if the token isn't already known to be (is/was) valid.
9684 Sync { responder: NodeSyncResponder },
9685 /// On a BufferCollectionToken channel:
9686 ///
9687 /// Normally a participant will convert a BufferCollectionToken into a
9688 /// BufferCollection view, but a participant is also free to Close() the
9689 /// token (and then close the channel immediately or shortly later in
9690 /// response to server closing its end), which avoids causing logical buffer
9691 /// collection failure. Â Normally an unexpected token channel close will
9692 /// cause logical buffer collection failure (the only exceptions being
9693 /// certain cases involving AttachToken() or SetDispensable()).
9694 ///
9695 /// On a BufferCollection channel:
9696 ///
9697 /// By default the server handles unexpected failure of a BufferCollection
9698 /// by failing the whole logical buffer collection. Partly this is to
9699 /// expedite closing VMO handles to reclaim memory when any participant
9700 /// fails. If a participant would like to cleanly close a BufferCollection
9701 /// view without causing logical buffer collection failure, the participant
9702 /// can send Close() before closing the client end of the BufferCollection
9703 /// channel. If this is the last BufferCollection view, the logical buffer
9704 /// collection will still go away. The Close() can occur before or after
9705 /// SetConstraints(). If before SetConstraints(), the buffer collection
9706 /// won't require constraints from this node in order to allocate. If
9707 /// after SetConstraints(), the constraints are retained and aggregated
9708 /// along with any subsequent logical allocation(s), despite the lack of
9709 /// channel connection.
9710 ///
9711 /// On a BufferCollectionTokenGroup channel:
9712 ///
9713 /// By default, unexpected failure of a BufferCollectionTokenGroup will
9714 /// trigger failure of the logical BufferCollectionTokenGroup and will
9715 /// propagate failure to its parent. To close a BufferCollectionTokenGroup
9716 /// channel without failing the logical group or propagating failure, send
9717 /// Close() before closing the channel client endpoint.
9718 ///
9719 /// If Close() occurs before AllChildrenPresent(), the logical buffer
9720 /// collection will still fail despite the Close() (because sysmem can't be
9721 /// sure whether all relevant children were created, so it's ambiguous
9722 /// whether all relevant constraints will be provided to sysmem). If
9723 /// Close() occurs after AllChildrenPresent(), the children and all their
9724 /// constraints remain intact (just as they would if the
9725 /// BufferCollectionTokenGroup channel had remained open), and the close
9726 /// doesn't trigger or propagate failure.
9727 Close { control_handle: NodeControlHandle },
9728 /// Set a name for VMOs in this buffer collection. The name may be truncated
9729 /// shorter. The name only affects VMOs allocated after it's set - this call
9730 /// does not rename existing VMOs. If multiple clients set different names
9731 /// then the larger priority value will win.
9732 SetName { priority: u32, name: String, control_handle: NodeControlHandle },
9733 /// Set information about the current client that can be used by sysmem to
9734 /// help debug leaking memory and hangs waiting for constraints. |name| can
9735 /// be an arbitrary string, but the current process name (see
9736 /// fsl::GetCurrentProcessName()) is a good default. |id| can be an
9737 /// arbitrary id, but the current process ID (see
9738 /// fsl::GetCurrentProcessKoid()) is a good default.
9739 ///
9740 /// Also used when verbose logging is enabled (see SetVerboseLogging()) to
9741 /// indicate which client is closing their channel first, leading to
9742 /// sub-tree failure (which can be normal if the purpose of the sub-tree is
9743 /// over, but if happening earlier than expected, the
9744 /// client-channel-specific name can help diagnose where the failure is
9745 /// first coming from, from sysmem's point of view).
9746 ///
9747 /// By default (unless overriden by this message or using
9748 /// Allocator.SetDebugClientInfo()), a Node will copy info from its
9749 /// parent Node at the time the child Node is created. While this can be
9750 /// better than nothing, it's often better for each participant to use
9751 /// Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the
9752 /// info directly relevant to the current client. Also, SetVerboseLogging()
9753 /// can be used to help disambiguate if a Node is suspected of having info
9754 /// that was copied from its parent.
9755 SetDebugClientInfo { name: String, id: u64, control_handle: NodeControlHandle },
9756 /// Sysmem logs a warning if not all clients have set constraints 5 seconds
9757 /// after creating a collection. Clients can call this method to change
9758 /// when the log is printed. If multiple client set the deadline, it's
9759 /// unspecified which deadline will take effect.
9760 SetDebugTimeoutLogDeadline { deadline: i64, control_handle: NodeControlHandle },
9761 /// Verbose logging includes constraints set via SetConstraints() from each
9762 /// client along with info set via SetDebugClientInfo() and the structure of
9763 /// the tree of Node(s).
9764 ///
9765 /// Normally sysmem prints only a single line complaint when aggregation
9766 /// fails, with just the specific detailed reason that aggregation failed,
9767 /// with minimal context. While this is often enough to diagnose a problem
9768 /// if only a small change was made and the system had been working before
9769 /// the small change, it's often not particularly helpful for getting a new
9770 /// buffer collection to work for the first time. Especially with more
9771 /// complex trees of nodes, involving things like AttachToken(),
9772 /// SetDispensable(), BufferCollectionTokenGroup nodes, and associated
9773 /// sub-trees of nodes, verbose logging may help in diagnosing what the tree
9774 /// looks like and why it's failing a logical allocation, or why a tree or
9775 /// sub-tree is failing sooner than expected.
9776 ///
9777 /// The intent of the extra logging is to be acceptable from a performance
9778 /// point of view, if only enabled on a low number of buffer collections.
9779 /// If we're not tracking down a bug, we shouldn't send this message.
9780 ///
9781 /// If too many participants leave verbose logging enabled, we may end up
9782 /// needing to require that system-wide sysmem verbose logging be permitted
9783 /// via some other setting, to avoid sysmem spamming the log too much due to
9784 /// this message.
9785 ///
9786 /// This may be a NOP for some nodes due to intentional policy associated
9787 /// with the node, if we don't trust a node enough to let it turn on verbose
9788 /// logging.
9789 SetVerboseLogging { control_handle: NodeControlHandle },
9790 /// This gets an event handle that can be used as a parameter to
9791 /// IsAlternateFor() called on any Node. The client will not be granted the
9792 /// right to signal this event, as this handle should only be used as proof
9793 /// that the client obtained this handle from this Node.
9794 ///
9795 /// Because this is a get not a set, no Sync() is needed between the
9796 /// GetNodeRef() and the call to IsAlternateFor(), despite the two calls
9797 /// potentially being on different channels.
9798 ///
9799 /// See also IsAlternateFor().
9800 GetNodeRef { responder: NodeGetNodeRefResponder },
9801 /// This checks whether the calling node is in a subtree rooted at a
9802 /// different child token of a common parent BufferCollectionTokenGroup, in
9803 /// relation to the passed-in node_ref.
9804 ///
9805 /// This call is for assisting with admission control de-duplication, and
9806 /// with debugging.
9807 ///
9808 /// The node_ref must be obtained using GetNodeRef() of a
9809 /// BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.
9810 ///
9811 /// The node_ref can be a duplicated handle; it's not necessary to call
9812 /// GetNodeRef() for every call to IsAlternateFor().
9813 ///
9814 /// If a calling token may not actually be a valid token at all due to
9815 /// a potentially hostile/untrusted provider of the token, call
9816 /// ValidateBufferCollectionToken() first instead of potentially getting
9817 /// stuck indefinitely if IsAlternateFor() never responds due to a calling
9818 /// token not being a real token (not really talking to sysmem). Another
9819 /// option is to call BindSharedCollection with this token first which also
9820 /// validates the token along with converting it to a BufferCollection, then
9821 /// call BufferCollection IsAlternateFor().
9822 ///
9823 /// error values:
9824 ///
9825 /// ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical
9826 /// buffer collection as the calling Node. Before logical allocation and
9827 /// within the same logical allocation sub-tree, this essentially means that
9828 /// the node_ref was never part of this logical buffer collection, since
9829 /// before logical allocation all node_refs that come into existence remain
9830 /// in existence at least until logical allocation (including Node(s) that
9831 /// have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND
9832 /// to be returned, this Node's channel needs to still be connected server
9833 /// side, which won't be the case if the whole logical allocation has
9834 /// failed. After logical allocation or in a different logical allocation
9835 /// sub-tree there are additional potential reasons for this error. For
9836 /// example a different logical allocation (separated from this Node(s)
9837 /// logical allocation by an AttachToken() or SetDispensable()) can fail its
9838 /// sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may
9839 /// exist and may select a different child sub-tree than the sub-tree the
9840 /// node_ref is in causing deletion of the node_ref Node. The only time
9841 /// sysmem keeps a Node around after that Node has no corresponding channel
9842 /// is when Close() is used and the Node's sub-tree has not yet failed.
9843 /// Another reason for this error is if the node_ref is an eventpair handle
9844 /// with sufficient rights, but isn't actually a real node_ref obtained from
9845 /// GetNodeRef().
9846 ///
9847 /// ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an
9848 /// eventpair handle, or doesn't have the needed rights expected on a real
9849 /// node_ref.
9850 ///
9851 /// No other failing status codes are returned by this call. However,
9852 /// sysmem may add additional codes in future, so the client should have
9853 /// sensible default handling for any failing status code.
9854 ///
9855 /// On success, is_alternate has the following meaning:
9856 /// * true - The first parent node in common between the calling node and
9857 /// the node_ref Node is a BufferCollectionTokenGroup. This means that
9858 /// the calling Node and the node_ref Node will _not_ have both their
9859 /// constraints apply - rather sysmem will choose one or the other of
9860 /// the constraints - never both. This is because only one child of
9861 /// a BufferCollectionTokenGroup is selected during logical allocation,
9862 /// with only that one child's sub-tree contributing to constraints
9863 /// aggregation.
9864 /// * false - The first parent node in common between the calling Node and
9865 /// the node_ref Node is not a BufferCollectionTokenGroup. Currently,
9866 /// this means the first parent node in common is a
9867 /// BufferCollectionToken or BufferCollection (regardless of not
9868 /// Close()ed or Close()ed). This means that the calling Node and the
9869 /// node_ref Node _may_ have both their constraints apply during
9870 /// constraints aggregation of the logical allocation, if both Node(s)
9871 /// are selected by any parent BufferCollectionTokenGroup(s) involved.
9872 /// In this case, there is no BufferCollectionTokenGroup that will
9873 /// directly prevent the two Node(s) from both being selected and their
9874 /// constraints both aggregated, but even when false, one or both
9875 /// Node(s) may still be eliminated from consideration if one or both
9876 /// Node(s) has a direct or indirect parent BufferCollectionTokenGroup
9877 /// which selects a child sub-tree other than the sub-tree containing
9878 /// the calling Node or node_ref Node.
9879 IsAlternateFor { node_ref: fidl::Event, responder: NodeIsAlternateForResponder },
9880}
9881
9882impl NodeRequest {
9883 #[allow(irrefutable_let_patterns)]
9884 pub fn into_sync(self) -> Option<(NodeSyncResponder)> {
9885 if let NodeRequest::Sync { responder } = self { Some((responder)) } else { None }
9886 }
9887
9888 #[allow(irrefutable_let_patterns)]
9889 pub fn into_close(self) -> Option<(NodeControlHandle)> {
9890 if let NodeRequest::Close { control_handle } = self { Some((control_handle)) } else { None }
9891 }
9892
9893 #[allow(irrefutable_let_patterns)]
9894 pub fn into_set_name(self) -> Option<(u32, String, NodeControlHandle)> {
9895 if let NodeRequest::SetName { priority, name, control_handle } = self {
9896 Some((priority, name, control_handle))
9897 } else {
9898 None
9899 }
9900 }
9901
9902 #[allow(irrefutable_let_patterns)]
9903 pub fn into_set_debug_client_info(self) -> Option<(String, u64, NodeControlHandle)> {
9904 if let NodeRequest::SetDebugClientInfo { name, id, control_handle } = self {
9905 Some((name, id, control_handle))
9906 } else {
9907 None
9908 }
9909 }
9910
9911 #[allow(irrefutable_let_patterns)]
9912 pub fn into_set_debug_timeout_log_deadline(self) -> Option<(i64, NodeControlHandle)> {
9913 if let NodeRequest::SetDebugTimeoutLogDeadline { deadline, control_handle } = self {
9914 Some((deadline, control_handle))
9915 } else {
9916 None
9917 }
9918 }
9919
9920 #[allow(irrefutable_let_patterns)]
9921 pub fn into_set_verbose_logging(self) -> Option<(NodeControlHandle)> {
9922 if let NodeRequest::SetVerboseLogging { control_handle } = self {
9923 Some((control_handle))
9924 } else {
9925 None
9926 }
9927 }
9928
9929 #[allow(irrefutable_let_patterns)]
9930 pub fn into_get_node_ref(self) -> Option<(NodeGetNodeRefResponder)> {
9931 if let NodeRequest::GetNodeRef { responder } = self { Some((responder)) } else { None }
9932 }
9933
9934 #[allow(irrefutable_let_patterns)]
9935 pub fn into_is_alternate_for(self) -> Option<(fidl::Event, NodeIsAlternateForResponder)> {
9936 if let NodeRequest::IsAlternateFor { node_ref, responder } = self {
9937 Some((node_ref, responder))
9938 } else {
9939 None
9940 }
9941 }
9942
9943 /// Name of the method defined in FIDL
9944 pub fn method_name(&self) -> &'static str {
9945 match *self {
9946 NodeRequest::Sync { .. } => "sync",
9947 NodeRequest::Close { .. } => "close",
9948 NodeRequest::SetName { .. } => "set_name",
9949 NodeRequest::SetDebugClientInfo { .. } => "set_debug_client_info",
9950 NodeRequest::SetDebugTimeoutLogDeadline { .. } => "set_debug_timeout_log_deadline",
9951 NodeRequest::SetVerboseLogging { .. } => "set_verbose_logging",
9952 NodeRequest::GetNodeRef { .. } => "get_node_ref",
9953 NodeRequest::IsAlternateFor { .. } => "is_alternate_for",
9954 }
9955 }
9956}
9957
9958#[derive(Debug, Clone)]
9959pub struct NodeControlHandle {
9960 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
9961}
9962
9963impl NodeControlHandle {
9964 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
9965 self.inner.shutdown_with_epitaph(status.into())
9966 }
9967}
9968
9969impl fidl::endpoints::ControlHandle for NodeControlHandle {
9970 fn shutdown(&self) {
9971 self.inner.shutdown()
9972 }
9973
9974 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
9975 self.inner.shutdown_with_epitaph(status)
9976 }
9977
9978 fn is_closed(&self) -> bool {
9979 self.inner.channel().is_closed()
9980 }
9981 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
9982 self.inner.channel().on_closed()
9983 }
9984
9985 #[cfg(target_os = "fuchsia")]
9986 fn signal_peer(
9987 &self,
9988 clear_mask: zx::Signals,
9989 set_mask: zx::Signals,
9990 ) -> Result<(), zx_status::Status> {
9991 use fidl::Peered;
9992 self.inner.channel().signal_peer(clear_mask, set_mask)
9993 }
9994}
9995
9996impl NodeControlHandle {}
9997
9998#[must_use = "FIDL methods require a response to be sent"]
9999#[derive(Debug)]
10000pub struct NodeSyncResponder {
10001 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
10002 tx_id: u32,
10003}
10004
10005/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
10006/// if the responder is dropped without sending a response, so that the client
10007/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
10008impl std::ops::Drop for NodeSyncResponder {
10009 fn drop(&mut self) {
10010 self.control_handle.shutdown();
10011 // Safety: drops once, never accessed again
10012 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10013 }
10014}
10015
10016impl fidl::endpoints::Responder for NodeSyncResponder {
10017 type ControlHandle = NodeControlHandle;
10018
10019 fn control_handle(&self) -> &NodeControlHandle {
10020 &self.control_handle
10021 }
10022
10023 fn drop_without_shutdown(mut self) {
10024 // Safety: drops once, never accessed again due to mem::forget
10025 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10026 // Prevent Drop from running (which would shut down the channel)
10027 std::mem::forget(self);
10028 }
10029}
10030
10031impl NodeSyncResponder {
10032 /// Sends a response to the FIDL transaction.
10033 ///
10034 /// Sets the channel to shutdown if an error occurs.
10035 pub fn send(self) -> Result<(), fidl::Error> {
10036 let _result = self.send_raw();
10037 if _result.is_err() {
10038 self.control_handle.shutdown();
10039 }
10040 self.drop_without_shutdown();
10041 _result
10042 }
10043
10044 /// Similar to "send" but does not shutdown the channel if an error occurs.
10045 pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
10046 let _result = self.send_raw();
10047 self.drop_without_shutdown();
10048 _result
10049 }
10050
10051 fn send_raw(&self) -> Result<(), fidl::Error> {
10052 self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
10053 (),
10054 self.tx_id,
10055 0x4577e238ae26291,
10056 fidl::encoding::DynamicFlags::empty(),
10057 )
10058 }
10059}
10060
10061#[must_use = "FIDL methods require a response to be sent"]
10062#[derive(Debug)]
10063pub struct NodeGetNodeRefResponder {
10064 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
10065 tx_id: u32,
10066}
10067
10068/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
10069/// if the responder is dropped without sending a response, so that the client
10070/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
10071impl std::ops::Drop for NodeGetNodeRefResponder {
10072 fn drop(&mut self) {
10073 self.control_handle.shutdown();
10074 // Safety: drops once, never accessed again
10075 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10076 }
10077}
10078
10079impl fidl::endpoints::Responder for NodeGetNodeRefResponder {
10080 type ControlHandle = NodeControlHandle;
10081
10082 fn control_handle(&self) -> &NodeControlHandle {
10083 &self.control_handle
10084 }
10085
10086 fn drop_without_shutdown(mut self) {
10087 // Safety: drops once, never accessed again due to mem::forget
10088 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10089 // Prevent Drop from running (which would shut down the channel)
10090 std::mem::forget(self);
10091 }
10092}
10093
10094impl NodeGetNodeRefResponder {
10095 /// Sends a response to the FIDL transaction.
10096 ///
10097 /// Sets the channel to shutdown if an error occurs.
10098 pub fn send(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10099 let _result = self.send_raw(node_ref);
10100 if _result.is_err() {
10101 self.control_handle.shutdown();
10102 }
10103 self.drop_without_shutdown();
10104 _result
10105 }
10106
10107 /// Similar to "send" but does not shutdown the channel if an error occurs.
10108 pub fn send_no_shutdown_on_err(self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10109 let _result = self.send_raw(node_ref);
10110 self.drop_without_shutdown();
10111 _result
10112 }
10113
10114 fn send_raw(&self, mut node_ref: fidl::Event) -> Result<(), fidl::Error> {
10115 self.control_handle.inner.send::<NodeGetNodeRefResponse>(
10116 (node_ref,),
10117 self.tx_id,
10118 0x467b7c75c35c3b84,
10119 fidl::encoding::DynamicFlags::empty(),
10120 )
10121 }
10122}
10123
10124#[must_use = "FIDL methods require a response to be sent"]
10125#[derive(Debug)]
10126pub struct NodeIsAlternateForResponder {
10127 control_handle: std::mem::ManuallyDrop<NodeControlHandle>,
10128 tx_id: u32,
10129}
10130
10131/// Set the the channel to be shutdown (see [`NodeControlHandle::shutdown`])
10132/// if the responder is dropped without sending a response, so that the client
10133/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
10134impl std::ops::Drop for NodeIsAlternateForResponder {
10135 fn drop(&mut self) {
10136 self.control_handle.shutdown();
10137 // Safety: drops once, never accessed again
10138 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10139 }
10140}
10141
10142impl fidl::endpoints::Responder for NodeIsAlternateForResponder {
10143 type ControlHandle = NodeControlHandle;
10144
10145 fn control_handle(&self) -> &NodeControlHandle {
10146 &self.control_handle
10147 }
10148
10149 fn drop_without_shutdown(mut self) {
10150 // Safety: drops once, never accessed again due to mem::forget
10151 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
10152 // Prevent Drop from running (which would shut down the channel)
10153 std::mem::forget(self);
10154 }
10155}
10156
10157impl NodeIsAlternateForResponder {
10158 /// Sends a response to the FIDL transaction.
10159 ///
10160 /// Sets the channel to shutdown if an error occurs.
10161 pub fn send(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10162 let _result = self.send_raw(result);
10163 if _result.is_err() {
10164 self.control_handle.shutdown();
10165 }
10166 self.drop_without_shutdown();
10167 _result
10168 }
10169
10170 /// Similar to "send" but does not shutdown the channel if an error occurs.
10171 pub fn send_no_shutdown_on_err(self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10172 let _result = self.send_raw(result);
10173 self.drop_without_shutdown();
10174 _result
10175 }
10176
10177 fn send_raw(&self, mut result: Result<bool, i32>) -> Result<(), fidl::Error> {
10178 self.control_handle
10179 .inner
10180 .send::<fidl::encoding::ResultType<NodeIsAlternateForResponse, i32>>(
10181 result.map(|is_alternate| (is_alternate,)),
10182 self.tx_id,
10183 0x33a2a7aff2776c07,
10184 fidl::encoding::DynamicFlags::empty(),
10185 )
10186 }
10187}
10188
10189#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
10190pub struct SecureMemMarker;
10191
10192impl fidl::endpoints::ProtocolMarker for SecureMemMarker {
10193 type Proxy = SecureMemProxy;
10194 type RequestStream = SecureMemRequestStream;
10195 #[cfg(target_os = "fuchsia")]
10196 type SynchronousProxy = SecureMemSynchronousProxy;
10197
10198 const DEBUG_NAME: &'static str = "(anonymous) SecureMem";
10199}
10200pub type SecureMemGetPhysicalSecureHeapsResult = Result<SecureHeapsAndRanges, i32>;
10201pub type SecureMemGetPhysicalSecureHeapPropertiesResult = Result<SecureHeapProperties, i32>;
10202pub type SecureMemAddSecureHeapPhysicalRangeResult = Result<(), i32>;
10203pub type SecureMemDeleteSecureHeapPhysicalRangeResult = Result<(), i32>;
10204pub type SecureMemModifySecureHeapPhysicalRangeResult = Result<(), i32>;
10205pub type SecureMemZeroSubRangeResult = Result<(), i32>;
10206
10207pub trait SecureMemProxyInterface: Send + Sync {
10208 type GetPhysicalSecureHeapsResponseFut: std::future::Future<Output = Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error>>
10209 + Send;
10210 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut;
10211 type GetPhysicalSecureHeapPropertiesResponseFut: std::future::Future<
10212 Output = Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error>,
10213 > + Send;
10214 fn r#get_physical_secure_heap_properties(
10215 &self,
10216 entire_heap: &SecureHeapAndRange,
10217 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut;
10218 type AddSecureHeapPhysicalRangeResponseFut: std::future::Future<Output = Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error>>
10219 + Send;
10220 fn r#add_secure_heap_physical_range(
10221 &self,
10222 heap_range: &SecureHeapAndRange,
10223 ) -> Self::AddSecureHeapPhysicalRangeResponseFut;
10224 type DeleteSecureHeapPhysicalRangeResponseFut: std::future::Future<
10225 Output = Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error>,
10226 > + Send;
10227 fn r#delete_secure_heap_physical_range(
10228 &self,
10229 heap_range: &SecureHeapAndRange,
10230 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut;
10231 type ModifySecureHeapPhysicalRangeResponseFut: std::future::Future<
10232 Output = Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error>,
10233 > + Send;
10234 fn r#modify_secure_heap_physical_range(
10235 &self,
10236 range_modification: &SecureHeapAndRangeModification,
10237 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut;
10238 type ZeroSubRangeResponseFut: std::future::Future<Output = Result<SecureMemZeroSubRangeResult, fidl::Error>>
10239 + Send;
10240 fn r#zero_sub_range(
10241 &self,
10242 is_covering_range_explicit: bool,
10243 heap_range: &SecureHeapAndRange,
10244 ) -> Self::ZeroSubRangeResponseFut;
10245}
10246#[derive(Debug)]
10247#[cfg(target_os = "fuchsia")]
10248pub struct SecureMemSynchronousProxy {
10249 client: fidl::client::sync::Client,
10250}
10251
10252#[cfg(target_os = "fuchsia")]
10253impl fidl::endpoints::SynchronousProxy for SecureMemSynchronousProxy {
10254 type Proxy = SecureMemProxy;
10255 type Protocol = SecureMemMarker;
10256
10257 fn from_channel(inner: fidl::Channel) -> Self {
10258 Self::new(inner)
10259 }
10260
10261 fn into_channel(self) -> fidl::Channel {
10262 self.client.into_channel()
10263 }
10264
10265 fn as_channel(&self) -> &fidl::Channel {
10266 self.client.as_channel()
10267 }
10268}
10269
10270#[cfg(target_os = "fuchsia")]
10271impl SecureMemSynchronousProxy {
10272 pub fn new(channel: fidl::Channel) -> Self {
10273 Self { client: fidl::client::sync::Client::new(channel) }
10274 }
10275
10276 pub fn into_channel(self) -> fidl::Channel {
10277 self.client.into_channel()
10278 }
10279
10280 /// Waits until an event arrives and returns it. It is safe for other
10281 /// threads to make concurrent requests while waiting for an event.
10282 pub fn wait_for_event(
10283 &self,
10284 deadline: zx::MonotonicInstant,
10285 ) -> Result<SecureMemEvent, fidl::Error> {
10286 SecureMemEvent::decode(self.client.wait_for_event::<SecureMemMarker>(deadline)?)
10287 }
10288
10289 /// Gets the physical address and length of any secure heap whose physical
10290 /// range is configured via the TEE.
10291 ///
10292 /// Presently, these will be fixed physical addresses and lengths, with the
10293 /// location plumbed via the TEE.
10294 ///
10295 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
10296 /// when there isn't any special heap-specific per-VMO setup or teardown
10297 /// required.
10298 ///
10299 /// The physical range must be secured/protected by the TEE before the
10300 /// securemem driver responds to this request with success.
10301 ///
10302 /// Sysmem should only call this once. Returning zero heaps is not a
10303 /// failure.
10304 ///
10305 /// Errors:
10306 /// * ZX_ERR_BAD_STATE - called more than once.
10307 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10308 /// with TEE which doesn't generate zx_status_t errors).
10309 /// * other errors are allowed; any other errors should be treated the same
10310 /// as ZX_ERR_INTERNAL.
10311 pub fn r#get_physical_secure_heaps(
10312 &self,
10313 ___deadline: zx::MonotonicInstant,
10314 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
10315 let _response = self.client.send_query::<
10316 fidl::encoding::EmptyPayload,
10317 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapsResponse, i32>,
10318 SecureMemMarker,
10319 >(
10320 (),
10321 0x782319d6ce7fa05,
10322 fidl::encoding::DynamicFlags::empty(),
10323 ___deadline,
10324 )?;
10325 Ok(_response.map(|x| x.heaps))
10326 }
10327
10328 /// This request from sysmem to the securemem driver gets the properties of
10329 /// a protected/secure heap.
10330 ///
10331 /// This only handles heaps with a single contiguous physical extent.
10332 ///
10333 /// The heap's entire physical range is indicated in case this request needs
10334 /// some physical space to auto-detect how many ranges are REE-usable. Any
10335 /// temporary HW protection ranges will be deleted before this request
10336 /// completes.
10337 pub fn r#get_physical_secure_heap_properties(
10338 &self,
10339 mut entire_heap: &SecureHeapAndRange,
10340 ___deadline: zx::MonotonicInstant,
10341 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
10342 let _response = self.client.send_query::<
10343 SecureMemGetPhysicalSecureHeapPropertiesRequest,
10344 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapPropertiesResponse, i32>,
10345 SecureMemMarker,
10346 >(
10347 (entire_heap,),
10348 0x26404e23f1271214,
10349 fidl::encoding::DynamicFlags::empty(),
10350 ___deadline,
10351 )?;
10352 Ok(_response.map(|x| x.properties))
10353 }
10354
10355 /// This request from sysmem to the securemem driver conveys a physical
10356 /// range to add, for a heap whose physical range(s) are set up via
10357 /// sysmem.
10358 ///
10359 /// Only sysmem can call this because only sysmem is handed the client end
10360 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10361 /// securemem driver is the server end of this protocol.
10362 ///
10363 /// The securemem driver must configure all the covered offsets as protected
10364 /// before responding to this message with success.
10365 ///
10366 /// On failure, the securemem driver must ensure the protected range was not
10367 /// created.
10368 ///
10369 /// Sysmem must only call this up to once if dynamic_protection_ranges
10370 /// false.
10371 ///
10372 /// If dynamic_protection_ranges is true, sysmem can call this multiple
10373 /// times as long as the current number of ranges never exceeds
10374 /// max_protected_range_count.
10375 ///
10376 /// The caller must not attempt to add a range that matches an
10377 /// already-existing range. Added ranges can overlap each other as long as
10378 /// no two ranges match exactly.
10379 ///
10380 /// Errors:
10381 /// * ZX_ERR_BAD_STATE - called more than once when
10382 /// !dynamic_protection_ranges. Adding a heap that would cause overall
10383 /// heap count to exceed max_protected_range_count.
10384 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10385 /// to protected_range_granularity.
10386 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10387 /// with TEE which doesn't generate zx_status_t errors).
10388 /// * other errors are possible, such as from communication failures or
10389 /// server propagation of zx_status_t failures.
10390 pub fn r#add_secure_heap_physical_range(
10391 &self,
10392 mut heap_range: &SecureHeapAndRange,
10393 ___deadline: zx::MonotonicInstant,
10394 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
10395 let _response = self.client.send_query::<
10396 SecureMemAddSecureHeapPhysicalRangeRequest,
10397 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10398 SecureMemMarker,
10399 >(
10400 (heap_range,),
10401 0x1ca1abcee8a0b33e,
10402 fidl::encoding::DynamicFlags::empty(),
10403 ___deadline,
10404 )?;
10405 Ok(_response.map(|x| x))
10406 }
10407
10408 /// This request from sysmem to the securemem driver conveys a physical
10409 /// range to delete, for a heap whose physical range(s) are set up via
10410 /// sysmem.
10411 ///
10412 /// Only sysmem can call this because only sysmem is handed the client end
10413 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10414 /// securemem driver is the server end of this protocol.
10415 ///
10416 /// The securemem driver must configure all the covered offsets as not
10417 /// protected before responding to this message with success.
10418 ///
10419 /// On failure, the securemem driver must ensure the protected range was not
10420 /// deleted.
10421 ///
10422 /// Sysmem must not call this if dynamic_protection_ranges false.
10423 ///
10424 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10425 /// on various ranges that exist at the time of the call.
10426 ///
10427 /// If any portion of the range being deleted is not also covered by another
10428 /// protected range, then any ongoing DMA to any part of the entire range
10429 /// may be interrupted / may fail, potentially in a way that's disruptive to
10430 /// the entire system (bus lockup or similar, depending on device details).
10431 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
10432 /// any portion of the range being deleted, unless the caller has other
10433 /// active ranges covering every block of the range being deleted. Ongoing
10434 /// DMA to/from blocks outside the range being deleted is never impacted by
10435 /// the deletion.
10436 ///
10437 /// Errors:
10438 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10439 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10440 /// to protected_range_granularity.
10441 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10442 /// with TEE which doesn't generate zx_status_t errors).
10443 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10444 /// * other errors are possible, such as from communication failures or
10445 /// server propagation of zx_status_t failures.
10446 pub fn r#delete_secure_heap_physical_range(
10447 &self,
10448 mut heap_range: &SecureHeapAndRange,
10449 ___deadline: zx::MonotonicInstant,
10450 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
10451 let _response = self.client.send_query::<
10452 SecureMemDeleteSecureHeapPhysicalRangeRequest,
10453 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10454 SecureMemMarker,
10455 >(
10456 (heap_range,),
10457 0x728a953e56df92ee,
10458 fidl::encoding::DynamicFlags::empty(),
10459 ___deadline,
10460 )?;
10461 Ok(_response.map(|x| x))
10462 }
10463
10464 /// This request from sysmem to the securemem driver conveys a physical
10465 /// range to modify and its new base and length, for a heap whose physical
10466 /// range(s) are set up via sysmem.
10467 ///
10468 /// Only sysmem can call this because only sysmem is handed the client end
10469 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10470 /// securemem driver is the server end of this protocol.
10471 ///
10472 /// The securemem driver must configure the range to cover only the new
10473 /// offsets before responding to this message with success.
10474 ///
10475 /// On failure, the securemem driver must ensure the range was not changed.
10476 ///
10477 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
10478 /// must not call this if !is_mod_protected_range_available.
10479 ///
10480 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10481 /// on various ranges that exist at the time of the call.
10482 ///
10483 /// The range must only be modified at one end or the other, but not both.
10484 /// If the range is getting shorter, and the un-covered blocks are not
10485 /// covered by other active ranges, any ongoing DMA to the entire range
10486 /// that's geting shorter may fail in a way that disrupts the entire system
10487 /// (bus lockup or similar), so the caller must ensure that no DMA is
10488 /// ongoing to any portion of a range that is getting shorter, unless the
10489 /// blocks being un-covered by the modification to this range are all
10490 /// covered by other active ranges, in which case no disruption to ongoing
10491 /// DMA will occur.
10492 ///
10493 /// If a range is modified to become <= zero length, the range is deleted.
10494 ///
10495 /// Errors:
10496 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10497 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
10498 /// that doesn't conform to protected_range_granularity, or old_range
10499 /// and new_range differ in both begin and end (disallowed).
10500 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10501 /// with TEE which doesn't generate zx_status_t errors).
10502 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10503 /// * other errors are possible, such as from communication failures or
10504 /// server propagation of zx_status_t failures.
10505 pub fn r#modify_secure_heap_physical_range(
10506 &self,
10507 mut range_modification: &SecureHeapAndRangeModification,
10508 ___deadline: zx::MonotonicInstant,
10509 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
10510 let _response = self.client.send_query::<
10511 SecureMemModifySecureHeapPhysicalRangeRequest,
10512 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10513 SecureMemMarker,
10514 >(
10515 (range_modification,),
10516 0x154fbfa3646a890d,
10517 fidl::encoding::DynamicFlags::empty(),
10518 ___deadline,
10519 )?;
10520 Ok(_response.map(|x| x))
10521 }
10522
10523 /// Zero a sub-range of a currently-existing physical range added via
10524 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
10525 /// exactly one physical range, and must not overlap with any other
10526 /// physical range.
10527 ///
10528 /// is_covering_range_explicit - When true, the covering range must be one
10529 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
10530 /// possibly modified since. When false, the covering range must not
10531 /// be one of the ranges explicitly created via
10532 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
10533 /// a covering range not created via AddSecureHeapPhysicalRange(). The
10534 /// covering range is typically the entire physical range (or a range
10535 /// which covers even more) of a heap configured by the TEE and whose
10536 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
10537 ///
10538 /// Ongoing DMA is not disrupted by this request.
10539 pub fn r#zero_sub_range(
10540 &self,
10541 mut is_covering_range_explicit: bool,
10542 mut heap_range: &SecureHeapAndRange,
10543 ___deadline: zx::MonotonicInstant,
10544 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
10545 let _response = self.client.send_query::<
10546 SecureMemZeroSubRangeRequest,
10547 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10548 SecureMemMarker,
10549 >(
10550 (is_covering_range_explicit, heap_range,),
10551 0x7480f72bb5bc7e5b,
10552 fidl::encoding::DynamicFlags::empty(),
10553 ___deadline,
10554 )?;
10555 Ok(_response.map(|x| x))
10556 }
10557}
10558
10559#[cfg(target_os = "fuchsia")]
10560impl From<SecureMemSynchronousProxy> for zx::NullableHandle {
10561 fn from(value: SecureMemSynchronousProxy) -> Self {
10562 value.into_channel().into()
10563 }
10564}
10565
10566#[cfg(target_os = "fuchsia")]
10567impl From<fidl::Channel> for SecureMemSynchronousProxy {
10568 fn from(value: fidl::Channel) -> Self {
10569 Self::new(value)
10570 }
10571}
10572
10573#[cfg(target_os = "fuchsia")]
10574impl fidl::endpoints::FromClient for SecureMemSynchronousProxy {
10575 type Protocol = SecureMemMarker;
10576
10577 fn from_client(value: fidl::endpoints::ClientEnd<SecureMemMarker>) -> Self {
10578 Self::new(value.into_channel())
10579 }
10580}
10581
10582#[derive(Debug, Clone)]
10583pub struct SecureMemProxy {
10584 client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
10585}
10586
10587impl fidl::endpoints::Proxy for SecureMemProxy {
10588 type Protocol = SecureMemMarker;
10589
10590 fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
10591 Self::new(inner)
10592 }
10593
10594 fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
10595 self.client.into_channel().map_err(|client| Self { client })
10596 }
10597
10598 fn as_channel(&self) -> &::fidl::AsyncChannel {
10599 self.client.as_channel()
10600 }
10601}
10602
10603impl SecureMemProxy {
10604 /// Create a new Proxy for fuchsia.sysmem/SecureMem.
10605 pub fn new(channel: ::fidl::AsyncChannel) -> Self {
10606 let protocol_name = <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
10607 Self { client: fidl::client::Client::new(channel, protocol_name) }
10608 }
10609
10610 /// Get a Stream of events from the remote end of the protocol.
10611 ///
10612 /// # Panics
10613 ///
10614 /// Panics if the event stream was already taken.
10615 pub fn take_event_stream(&self) -> SecureMemEventStream {
10616 SecureMemEventStream { event_receiver: self.client.take_event_receiver() }
10617 }
10618
10619 /// Gets the physical address and length of any secure heap whose physical
10620 /// range is configured via the TEE.
10621 ///
10622 /// Presently, these will be fixed physical addresses and lengths, with the
10623 /// location plumbed via the TEE.
10624 ///
10625 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
10626 /// when there isn't any special heap-specific per-VMO setup or teardown
10627 /// required.
10628 ///
10629 /// The physical range must be secured/protected by the TEE before the
10630 /// securemem driver responds to this request with success.
10631 ///
10632 /// Sysmem should only call this once. Returning zero heaps is not a
10633 /// failure.
10634 ///
10635 /// Errors:
10636 /// * ZX_ERR_BAD_STATE - called more than once.
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 allowed; any other errors should be treated the same
10640 /// as ZX_ERR_INTERNAL.
10641 pub fn r#get_physical_secure_heaps(
10642 &self,
10643 ) -> fidl::client::QueryResponseFut<
10644 SecureMemGetPhysicalSecureHeapsResult,
10645 fidl::encoding::DefaultFuchsiaResourceDialect,
10646 > {
10647 SecureMemProxyInterface::r#get_physical_secure_heaps(self)
10648 }
10649
10650 /// This request from sysmem to the securemem driver gets the properties of
10651 /// a protected/secure heap.
10652 ///
10653 /// This only handles heaps with a single contiguous physical extent.
10654 ///
10655 /// The heap's entire physical range is indicated in case this request needs
10656 /// some physical space to auto-detect how many ranges are REE-usable. Any
10657 /// temporary HW protection ranges will be deleted before this request
10658 /// completes.
10659 pub fn r#get_physical_secure_heap_properties(
10660 &self,
10661 mut entire_heap: &SecureHeapAndRange,
10662 ) -> fidl::client::QueryResponseFut<
10663 SecureMemGetPhysicalSecureHeapPropertiesResult,
10664 fidl::encoding::DefaultFuchsiaResourceDialect,
10665 > {
10666 SecureMemProxyInterface::r#get_physical_secure_heap_properties(self, entire_heap)
10667 }
10668
10669 /// This request from sysmem to the securemem driver conveys a physical
10670 /// range to add, for a heap whose physical range(s) are set up via
10671 /// sysmem.
10672 ///
10673 /// Only sysmem can call this because only sysmem is handed the client end
10674 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10675 /// securemem driver is the server end of this protocol.
10676 ///
10677 /// The securemem driver must configure all the covered offsets as protected
10678 /// before responding to this message with success.
10679 ///
10680 /// On failure, the securemem driver must ensure the protected range was not
10681 /// created.
10682 ///
10683 /// Sysmem must only call this up to once if dynamic_protection_ranges
10684 /// false.
10685 ///
10686 /// If dynamic_protection_ranges is true, sysmem can call this multiple
10687 /// times as long as the current number of ranges never exceeds
10688 /// max_protected_range_count.
10689 ///
10690 /// The caller must not attempt to add a range that matches an
10691 /// already-existing range. Added ranges can overlap each other as long as
10692 /// no two ranges match exactly.
10693 ///
10694 /// Errors:
10695 /// * ZX_ERR_BAD_STATE - called more than once when
10696 /// !dynamic_protection_ranges. Adding a heap that would cause overall
10697 /// heap count to exceed max_protected_range_count.
10698 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10699 /// to protected_range_granularity.
10700 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10701 /// with TEE which doesn't generate zx_status_t errors).
10702 /// * other errors are possible, such as from communication failures or
10703 /// server propagation of zx_status_t failures.
10704 pub fn r#add_secure_heap_physical_range(
10705 &self,
10706 mut heap_range: &SecureHeapAndRange,
10707 ) -> fidl::client::QueryResponseFut<
10708 SecureMemAddSecureHeapPhysicalRangeResult,
10709 fidl::encoding::DefaultFuchsiaResourceDialect,
10710 > {
10711 SecureMemProxyInterface::r#add_secure_heap_physical_range(self, heap_range)
10712 }
10713
10714 /// This request from sysmem to the securemem driver conveys a physical
10715 /// range to delete, for a heap whose physical range(s) are set up via
10716 /// sysmem.
10717 ///
10718 /// Only sysmem can call this because only sysmem is handed the client end
10719 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10720 /// securemem driver is the server end of this protocol.
10721 ///
10722 /// The securemem driver must configure all the covered offsets as not
10723 /// protected before responding to this message with success.
10724 ///
10725 /// On failure, the securemem driver must ensure the protected range was not
10726 /// deleted.
10727 ///
10728 /// Sysmem must not call this if dynamic_protection_ranges false.
10729 ///
10730 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10731 /// on various ranges that exist at the time of the call.
10732 ///
10733 /// If any portion of the range being deleted is not also covered by another
10734 /// protected range, then any ongoing DMA to any part of the entire range
10735 /// may be interrupted / may fail, potentially in a way that's disruptive to
10736 /// the entire system (bus lockup or similar, depending on device details).
10737 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
10738 /// any portion of the range being deleted, unless the caller has other
10739 /// active ranges covering every block of the range being deleted. Ongoing
10740 /// DMA to/from blocks outside the range being deleted is never impacted by
10741 /// the deletion.
10742 ///
10743 /// Errors:
10744 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10745 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
10746 /// to protected_range_granularity.
10747 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10748 /// with TEE which doesn't generate zx_status_t errors).
10749 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10750 /// * other errors are possible, such as from communication failures or
10751 /// server propagation of zx_status_t failures.
10752 pub fn r#delete_secure_heap_physical_range(
10753 &self,
10754 mut heap_range: &SecureHeapAndRange,
10755 ) -> fidl::client::QueryResponseFut<
10756 SecureMemDeleteSecureHeapPhysicalRangeResult,
10757 fidl::encoding::DefaultFuchsiaResourceDialect,
10758 > {
10759 SecureMemProxyInterface::r#delete_secure_heap_physical_range(self, heap_range)
10760 }
10761
10762 /// This request from sysmem to the securemem driver conveys a physical
10763 /// range to modify and its new base and length, for a heap whose physical
10764 /// range(s) are set up via sysmem.
10765 ///
10766 /// Only sysmem can call this because only sysmem is handed the client end
10767 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
10768 /// securemem driver is the server end of this protocol.
10769 ///
10770 /// The securemem driver must configure the range to cover only the new
10771 /// offsets before responding to this message with success.
10772 ///
10773 /// On failure, the securemem driver must ensure the range was not changed.
10774 ///
10775 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
10776 /// must not call this if !is_mod_protected_range_available.
10777 ///
10778 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
10779 /// on various ranges that exist at the time of the call.
10780 ///
10781 /// The range must only be modified at one end or the other, but not both.
10782 /// If the range is getting shorter, and the un-covered blocks are not
10783 /// covered by other active ranges, any ongoing DMA to the entire range
10784 /// that's geting shorter may fail in a way that disrupts the entire system
10785 /// (bus lockup or similar), so the caller must ensure that no DMA is
10786 /// ongoing to any portion of a range that is getting shorter, unless the
10787 /// blocks being un-covered by the modification to this range are all
10788 /// covered by other active ranges, in which case no disruption to ongoing
10789 /// DMA will occur.
10790 ///
10791 /// If a range is modified to become <= zero length, the range is deleted.
10792 ///
10793 /// Errors:
10794 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
10795 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
10796 /// that doesn't conform to protected_range_granularity, or old_range
10797 /// and new_range differ in both begin and end (disallowed).
10798 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
10799 /// with TEE which doesn't generate zx_status_t errors).
10800 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
10801 /// * other errors are possible, such as from communication failures or
10802 /// server propagation of zx_status_t failures.
10803 pub fn r#modify_secure_heap_physical_range(
10804 &self,
10805 mut range_modification: &SecureHeapAndRangeModification,
10806 ) -> fidl::client::QueryResponseFut<
10807 SecureMemModifySecureHeapPhysicalRangeResult,
10808 fidl::encoding::DefaultFuchsiaResourceDialect,
10809 > {
10810 SecureMemProxyInterface::r#modify_secure_heap_physical_range(self, range_modification)
10811 }
10812
10813 /// Zero a sub-range of a currently-existing physical range added via
10814 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
10815 /// exactly one physical range, and must not overlap with any other
10816 /// physical range.
10817 ///
10818 /// is_covering_range_explicit - When true, the covering range must be one
10819 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
10820 /// possibly modified since. When false, the covering range must not
10821 /// be one of the ranges explicitly created via
10822 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
10823 /// a covering range not created via AddSecureHeapPhysicalRange(). The
10824 /// covering range is typically the entire physical range (or a range
10825 /// which covers even more) of a heap configured by the TEE and whose
10826 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
10827 ///
10828 /// Ongoing DMA is not disrupted by this request.
10829 pub fn r#zero_sub_range(
10830 &self,
10831 mut is_covering_range_explicit: bool,
10832 mut heap_range: &SecureHeapAndRange,
10833 ) -> fidl::client::QueryResponseFut<
10834 SecureMemZeroSubRangeResult,
10835 fidl::encoding::DefaultFuchsiaResourceDialect,
10836 > {
10837 SecureMemProxyInterface::r#zero_sub_range(self, is_covering_range_explicit, heap_range)
10838 }
10839}
10840
10841impl SecureMemProxyInterface for SecureMemProxy {
10842 type GetPhysicalSecureHeapsResponseFut = fidl::client::QueryResponseFut<
10843 SecureMemGetPhysicalSecureHeapsResult,
10844 fidl::encoding::DefaultFuchsiaResourceDialect,
10845 >;
10846 fn r#get_physical_secure_heaps(&self) -> Self::GetPhysicalSecureHeapsResponseFut {
10847 fn _decode(
10848 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10849 ) -> Result<SecureMemGetPhysicalSecureHeapsResult, fidl::Error> {
10850 let _response = fidl::client::decode_transaction_body::<
10851 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapsResponse, i32>,
10852 fidl::encoding::DefaultFuchsiaResourceDialect,
10853 0x782319d6ce7fa05,
10854 >(_buf?)?;
10855 Ok(_response.map(|x| x.heaps))
10856 }
10857 self.client.send_query_and_decode::<
10858 fidl::encoding::EmptyPayload,
10859 SecureMemGetPhysicalSecureHeapsResult,
10860 >(
10861 (),
10862 0x782319d6ce7fa05,
10863 fidl::encoding::DynamicFlags::empty(),
10864 _decode,
10865 )
10866 }
10867
10868 type GetPhysicalSecureHeapPropertiesResponseFut = fidl::client::QueryResponseFut<
10869 SecureMemGetPhysicalSecureHeapPropertiesResult,
10870 fidl::encoding::DefaultFuchsiaResourceDialect,
10871 >;
10872 fn r#get_physical_secure_heap_properties(
10873 &self,
10874 mut entire_heap: &SecureHeapAndRange,
10875 ) -> Self::GetPhysicalSecureHeapPropertiesResponseFut {
10876 fn _decode(
10877 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10878 ) -> Result<SecureMemGetPhysicalSecureHeapPropertiesResult, fidl::Error> {
10879 let _response = fidl::client::decode_transaction_body::<
10880 fidl::encoding::ResultType<SecureMemGetPhysicalSecureHeapPropertiesResponse, i32>,
10881 fidl::encoding::DefaultFuchsiaResourceDialect,
10882 0x26404e23f1271214,
10883 >(_buf?)?;
10884 Ok(_response.map(|x| x.properties))
10885 }
10886 self.client.send_query_and_decode::<
10887 SecureMemGetPhysicalSecureHeapPropertiesRequest,
10888 SecureMemGetPhysicalSecureHeapPropertiesResult,
10889 >(
10890 (entire_heap,),
10891 0x26404e23f1271214,
10892 fidl::encoding::DynamicFlags::empty(),
10893 _decode,
10894 )
10895 }
10896
10897 type AddSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10898 SecureMemAddSecureHeapPhysicalRangeResult,
10899 fidl::encoding::DefaultFuchsiaResourceDialect,
10900 >;
10901 fn r#add_secure_heap_physical_range(
10902 &self,
10903 mut heap_range: &SecureHeapAndRange,
10904 ) -> Self::AddSecureHeapPhysicalRangeResponseFut {
10905 fn _decode(
10906 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10907 ) -> Result<SecureMemAddSecureHeapPhysicalRangeResult, fidl::Error> {
10908 let _response = fidl::client::decode_transaction_body::<
10909 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10910 fidl::encoding::DefaultFuchsiaResourceDialect,
10911 0x1ca1abcee8a0b33e,
10912 >(_buf?)?;
10913 Ok(_response.map(|x| x))
10914 }
10915 self.client.send_query_and_decode::<
10916 SecureMemAddSecureHeapPhysicalRangeRequest,
10917 SecureMemAddSecureHeapPhysicalRangeResult,
10918 >(
10919 (heap_range,),
10920 0x1ca1abcee8a0b33e,
10921 fidl::encoding::DynamicFlags::empty(),
10922 _decode,
10923 )
10924 }
10925
10926 type DeleteSecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10927 SecureMemDeleteSecureHeapPhysicalRangeResult,
10928 fidl::encoding::DefaultFuchsiaResourceDialect,
10929 >;
10930 fn r#delete_secure_heap_physical_range(
10931 &self,
10932 mut heap_range: &SecureHeapAndRange,
10933 ) -> Self::DeleteSecureHeapPhysicalRangeResponseFut {
10934 fn _decode(
10935 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10936 ) -> Result<SecureMemDeleteSecureHeapPhysicalRangeResult, fidl::Error> {
10937 let _response = fidl::client::decode_transaction_body::<
10938 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10939 fidl::encoding::DefaultFuchsiaResourceDialect,
10940 0x728a953e56df92ee,
10941 >(_buf?)?;
10942 Ok(_response.map(|x| x))
10943 }
10944 self.client.send_query_and_decode::<
10945 SecureMemDeleteSecureHeapPhysicalRangeRequest,
10946 SecureMemDeleteSecureHeapPhysicalRangeResult,
10947 >(
10948 (heap_range,),
10949 0x728a953e56df92ee,
10950 fidl::encoding::DynamicFlags::empty(),
10951 _decode,
10952 )
10953 }
10954
10955 type ModifySecureHeapPhysicalRangeResponseFut = fidl::client::QueryResponseFut<
10956 SecureMemModifySecureHeapPhysicalRangeResult,
10957 fidl::encoding::DefaultFuchsiaResourceDialect,
10958 >;
10959 fn r#modify_secure_heap_physical_range(
10960 &self,
10961 mut range_modification: &SecureHeapAndRangeModification,
10962 ) -> Self::ModifySecureHeapPhysicalRangeResponseFut {
10963 fn _decode(
10964 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10965 ) -> Result<SecureMemModifySecureHeapPhysicalRangeResult, fidl::Error> {
10966 let _response = fidl::client::decode_transaction_body::<
10967 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10968 fidl::encoding::DefaultFuchsiaResourceDialect,
10969 0x154fbfa3646a890d,
10970 >(_buf?)?;
10971 Ok(_response.map(|x| x))
10972 }
10973 self.client.send_query_and_decode::<
10974 SecureMemModifySecureHeapPhysicalRangeRequest,
10975 SecureMemModifySecureHeapPhysicalRangeResult,
10976 >(
10977 (range_modification,),
10978 0x154fbfa3646a890d,
10979 fidl::encoding::DynamicFlags::empty(),
10980 _decode,
10981 )
10982 }
10983
10984 type ZeroSubRangeResponseFut = fidl::client::QueryResponseFut<
10985 SecureMemZeroSubRangeResult,
10986 fidl::encoding::DefaultFuchsiaResourceDialect,
10987 >;
10988 fn r#zero_sub_range(
10989 &self,
10990 mut is_covering_range_explicit: bool,
10991 mut heap_range: &SecureHeapAndRange,
10992 ) -> Self::ZeroSubRangeResponseFut {
10993 fn _decode(
10994 mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
10995 ) -> Result<SecureMemZeroSubRangeResult, fidl::Error> {
10996 let _response = fidl::client::decode_transaction_body::<
10997 fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>,
10998 fidl::encoding::DefaultFuchsiaResourceDialect,
10999 0x7480f72bb5bc7e5b,
11000 >(_buf?)?;
11001 Ok(_response.map(|x| x))
11002 }
11003 self.client
11004 .send_query_and_decode::<SecureMemZeroSubRangeRequest, SecureMemZeroSubRangeResult>(
11005 (is_covering_range_explicit, heap_range),
11006 0x7480f72bb5bc7e5b,
11007 fidl::encoding::DynamicFlags::empty(),
11008 _decode,
11009 )
11010 }
11011}
11012
11013pub struct SecureMemEventStream {
11014 event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
11015}
11016
11017impl std::marker::Unpin for SecureMemEventStream {}
11018
11019impl futures::stream::FusedStream for SecureMemEventStream {
11020 fn is_terminated(&self) -> bool {
11021 self.event_receiver.is_terminated()
11022 }
11023}
11024
11025impl futures::Stream for SecureMemEventStream {
11026 type Item = Result<SecureMemEvent, fidl::Error>;
11027
11028 fn poll_next(
11029 mut self: std::pin::Pin<&mut Self>,
11030 cx: &mut std::task::Context<'_>,
11031 ) -> std::task::Poll<Option<Self::Item>> {
11032 match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
11033 &mut self.event_receiver,
11034 cx
11035 )?) {
11036 Some(buf) => std::task::Poll::Ready(Some(SecureMemEvent::decode(buf))),
11037 None => std::task::Poll::Ready(None),
11038 }
11039 }
11040}
11041
11042#[derive(Debug)]
11043pub enum SecureMemEvent {}
11044
11045impl SecureMemEvent {
11046 /// Decodes a message buffer as a [`SecureMemEvent`].
11047 fn decode(
11048 mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
11049 ) -> Result<SecureMemEvent, fidl::Error> {
11050 let (bytes, _handles) = buf.split_mut();
11051 let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
11052 debug_assert_eq!(tx_header.tx_id, 0);
11053 match tx_header.ordinal {
11054 _ => Err(fidl::Error::UnknownOrdinal {
11055 ordinal: tx_header.ordinal,
11056 protocol_name: <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
11057 }),
11058 }
11059 }
11060}
11061
11062/// A Stream of incoming requests for fuchsia.sysmem/SecureMem.
11063pub struct SecureMemRequestStream {
11064 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11065 is_terminated: bool,
11066}
11067
11068impl std::marker::Unpin for SecureMemRequestStream {}
11069
11070impl futures::stream::FusedStream for SecureMemRequestStream {
11071 fn is_terminated(&self) -> bool {
11072 self.is_terminated
11073 }
11074}
11075
11076impl fidl::endpoints::RequestStream for SecureMemRequestStream {
11077 type Protocol = SecureMemMarker;
11078 type ControlHandle = SecureMemControlHandle;
11079
11080 fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
11081 Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
11082 }
11083
11084 fn control_handle(&self) -> Self::ControlHandle {
11085 SecureMemControlHandle { inner: self.inner.clone() }
11086 }
11087
11088 fn into_inner(
11089 self,
11090 ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
11091 {
11092 (self.inner, self.is_terminated)
11093 }
11094
11095 fn from_inner(
11096 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11097 is_terminated: bool,
11098 ) -> Self {
11099 Self { inner, is_terminated }
11100 }
11101}
11102
11103impl futures::Stream for SecureMemRequestStream {
11104 type Item = Result<SecureMemRequest, fidl::Error>;
11105
11106 fn poll_next(
11107 mut self: std::pin::Pin<&mut Self>,
11108 cx: &mut std::task::Context<'_>,
11109 ) -> std::task::Poll<Option<Self::Item>> {
11110 let this = &mut *self;
11111 if this.inner.check_shutdown(cx) {
11112 this.is_terminated = true;
11113 return std::task::Poll::Ready(None);
11114 }
11115 if this.is_terminated {
11116 panic!("polled SecureMemRequestStream after completion");
11117 }
11118 fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
11119 |bytes, handles| {
11120 match this.inner.channel().read_etc(cx, bytes, handles) {
11121 std::task::Poll::Ready(Ok(())) => {}
11122 std::task::Poll::Pending => return std::task::Poll::Pending,
11123 std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
11124 this.is_terminated = true;
11125 return std::task::Poll::Ready(None);
11126 }
11127 std::task::Poll::Ready(Err(e)) => {
11128 return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
11129 e.into(),
11130 ))));
11131 }
11132 }
11133
11134 // A message has been received from the channel
11135 let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
11136
11137 std::task::Poll::Ready(Some(match header.ordinal {
11138 0x782319d6ce7fa05 => {
11139 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11140 let mut req = fidl::new_empty!(
11141 fidl::encoding::EmptyPayload,
11142 fidl::encoding::DefaultFuchsiaResourceDialect
11143 );
11144 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
11145 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11146 Ok(SecureMemRequest::GetPhysicalSecureHeaps {
11147 responder: SecureMemGetPhysicalSecureHeapsResponder {
11148 control_handle: std::mem::ManuallyDrop::new(control_handle),
11149 tx_id: header.tx_id,
11150 },
11151 })
11152 }
11153 0x26404e23f1271214 => {
11154 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11155 let mut req = fidl::new_empty!(
11156 SecureMemGetPhysicalSecureHeapPropertiesRequest,
11157 fidl::encoding::DefaultFuchsiaResourceDialect
11158 );
11159 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemGetPhysicalSecureHeapPropertiesRequest>(&header, _body_bytes, handles, &mut req)?;
11160 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11161 Ok(SecureMemRequest::GetPhysicalSecureHeapProperties {
11162 entire_heap: req.entire_heap,
11163
11164 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder {
11165 control_handle: std::mem::ManuallyDrop::new(control_handle),
11166 tx_id: header.tx_id,
11167 },
11168 })
11169 }
11170 0x1ca1abcee8a0b33e => {
11171 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11172 let mut req = fidl::new_empty!(
11173 SecureMemAddSecureHeapPhysicalRangeRequest,
11174 fidl::encoding::DefaultFuchsiaResourceDialect
11175 );
11176 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemAddSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11177 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11178 Ok(SecureMemRequest::AddSecureHeapPhysicalRange {
11179 heap_range: req.heap_range,
11180
11181 responder: SecureMemAddSecureHeapPhysicalRangeResponder {
11182 control_handle: std::mem::ManuallyDrop::new(control_handle),
11183 tx_id: header.tx_id,
11184 },
11185 })
11186 }
11187 0x728a953e56df92ee => {
11188 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11189 let mut req = fidl::new_empty!(
11190 SecureMemDeleteSecureHeapPhysicalRangeRequest,
11191 fidl::encoding::DefaultFuchsiaResourceDialect
11192 );
11193 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemDeleteSecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11194 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11195 Ok(SecureMemRequest::DeleteSecureHeapPhysicalRange {
11196 heap_range: req.heap_range,
11197
11198 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder {
11199 control_handle: std::mem::ManuallyDrop::new(control_handle),
11200 tx_id: header.tx_id,
11201 },
11202 })
11203 }
11204 0x154fbfa3646a890d => {
11205 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11206 let mut req = fidl::new_empty!(
11207 SecureMemModifySecureHeapPhysicalRangeRequest,
11208 fidl::encoding::DefaultFuchsiaResourceDialect
11209 );
11210 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemModifySecureHeapPhysicalRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11211 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11212 Ok(SecureMemRequest::ModifySecureHeapPhysicalRange {
11213 range_modification: req.range_modification,
11214
11215 responder: SecureMemModifySecureHeapPhysicalRangeResponder {
11216 control_handle: std::mem::ManuallyDrop::new(control_handle),
11217 tx_id: header.tx_id,
11218 },
11219 })
11220 }
11221 0x7480f72bb5bc7e5b => {
11222 header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
11223 let mut req = fidl::new_empty!(
11224 SecureMemZeroSubRangeRequest,
11225 fidl::encoding::DefaultFuchsiaResourceDialect
11226 );
11227 fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<SecureMemZeroSubRangeRequest>(&header, _body_bytes, handles, &mut req)?;
11228 let control_handle = SecureMemControlHandle { inner: this.inner.clone() };
11229 Ok(SecureMemRequest::ZeroSubRange {
11230 is_covering_range_explicit: req.is_covering_range_explicit,
11231 heap_range: req.heap_range,
11232
11233 responder: SecureMemZeroSubRangeResponder {
11234 control_handle: std::mem::ManuallyDrop::new(control_handle),
11235 tx_id: header.tx_id,
11236 },
11237 })
11238 }
11239 _ => Err(fidl::Error::UnknownOrdinal {
11240 ordinal: header.ordinal,
11241 protocol_name:
11242 <SecureMemMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
11243 }),
11244 }))
11245 },
11246 )
11247 }
11248}
11249
11250/// SecureMem
11251///
11252/// The client is sysmem. The server is securemem driver.
11253///
11254/// TEE - Trusted Execution Environment.
11255///
11256/// REE - Rich Execution Environment.
11257///
11258/// Enables sysmem to call the securemem driver to get any secure heaps
11259/// configured via the TEE (or via the securemem driver), and set any physical
11260/// secure heaps configured via sysmem.
11261///
11262/// Presently, dynamically-allocated secure heaps are configured via sysmem, as
11263/// it starts quite early during boot and can successfully reserve contiguous
11264/// physical memory. Presently, fixed-location secure heaps are configured via
11265/// TEE, as the plumbing goes from the bootloader to the TEE. However, this
11266/// protocol intentionally doesn't care which heaps are dynamically-allocated
11267/// and which are fixed-location.
11268#[derive(Debug)]
11269pub enum SecureMemRequest {
11270 /// Gets the physical address and length of any secure heap whose physical
11271 /// range is configured via the TEE.
11272 ///
11273 /// Presently, these will be fixed physical addresses and lengths, with the
11274 /// location plumbed via the TEE.
11275 ///
11276 /// This is preferred over ['fuchsia.hardware.sysmem.Sysmem/RegisterHeap']
11277 /// when there isn't any special heap-specific per-VMO setup or teardown
11278 /// required.
11279 ///
11280 /// The physical range must be secured/protected by the TEE before the
11281 /// securemem driver responds to this request with success.
11282 ///
11283 /// Sysmem should only call this once. Returning zero heaps is not a
11284 /// failure.
11285 ///
11286 /// Errors:
11287 /// * ZX_ERR_BAD_STATE - called more than once.
11288 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11289 /// with TEE which doesn't generate zx_status_t errors).
11290 /// * other errors are allowed; any other errors should be treated the same
11291 /// as ZX_ERR_INTERNAL.
11292 GetPhysicalSecureHeaps { responder: SecureMemGetPhysicalSecureHeapsResponder },
11293 /// This request from sysmem to the securemem driver gets the properties of
11294 /// a protected/secure heap.
11295 ///
11296 /// This only handles heaps with a single contiguous physical extent.
11297 ///
11298 /// The heap's entire physical range is indicated in case this request needs
11299 /// some physical space to auto-detect how many ranges are REE-usable. Any
11300 /// temporary HW protection ranges will be deleted before this request
11301 /// completes.
11302 GetPhysicalSecureHeapProperties {
11303 entire_heap: SecureHeapAndRange,
11304 responder: SecureMemGetPhysicalSecureHeapPropertiesResponder,
11305 },
11306 /// This request from sysmem to the securemem driver conveys a physical
11307 /// range to add, for a heap whose physical range(s) are set up via
11308 /// sysmem.
11309 ///
11310 /// Only sysmem can call this because only sysmem is handed the client end
11311 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11312 /// securemem driver is the server end of this protocol.
11313 ///
11314 /// The securemem driver must configure all the covered offsets as protected
11315 /// before responding to this message with success.
11316 ///
11317 /// On failure, the securemem driver must ensure the protected range was not
11318 /// created.
11319 ///
11320 /// Sysmem must only call this up to once if dynamic_protection_ranges
11321 /// false.
11322 ///
11323 /// If dynamic_protection_ranges is true, sysmem can call this multiple
11324 /// times as long as the current number of ranges never exceeds
11325 /// max_protected_range_count.
11326 ///
11327 /// The caller must not attempt to add a range that matches an
11328 /// already-existing range. Added ranges can overlap each other as long as
11329 /// no two ranges match exactly.
11330 ///
11331 /// Errors:
11332 /// * ZX_ERR_BAD_STATE - called more than once when
11333 /// !dynamic_protection_ranges. Adding a heap that would cause overall
11334 /// heap count to exceed max_protected_range_count.
11335 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
11336 /// to protected_range_granularity.
11337 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11338 /// with TEE which doesn't generate zx_status_t errors).
11339 /// * other errors are possible, such as from communication failures or
11340 /// server propagation of zx_status_t failures.
11341 AddSecureHeapPhysicalRange {
11342 heap_range: SecureHeapAndRange,
11343 responder: SecureMemAddSecureHeapPhysicalRangeResponder,
11344 },
11345 /// This request from sysmem to the securemem driver conveys a physical
11346 /// range to delete, for a heap whose physical range(s) are set up via
11347 /// sysmem.
11348 ///
11349 /// Only sysmem can call this because only sysmem is handed the client end
11350 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11351 /// securemem driver is the server end of this protocol.
11352 ///
11353 /// The securemem driver must configure all the covered offsets as not
11354 /// protected before responding to this message with success.
11355 ///
11356 /// On failure, the securemem driver must ensure the protected range was not
11357 /// deleted.
11358 ///
11359 /// Sysmem must not call this if dynamic_protection_ranges false.
11360 ///
11361 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
11362 /// on various ranges that exist at the time of the call.
11363 ///
11364 /// If any portion of the range being deleted is not also covered by another
11365 /// protected range, then any ongoing DMA to any part of the entire range
11366 /// may be interrupted / may fail, potentially in a way that's disruptive to
11367 /// the entire system (bus lockup or similar, depending on device details).
11368 /// Therefore, the caller must ensure that no ongoing DMA is occurring to
11369 /// any portion of the range being deleted, unless the caller has other
11370 /// active ranges covering every block of the range being deleted. Ongoing
11371 /// DMA to/from blocks outside the range being deleted is never impacted by
11372 /// the deletion.
11373 ///
11374 /// Errors:
11375 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
11376 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform
11377 /// to protected_range_granularity.
11378 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11379 /// with TEE which doesn't generate zx_status_t errors).
11380 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
11381 /// * other errors are possible, such as from communication failures or
11382 /// server propagation of zx_status_t failures.
11383 DeleteSecureHeapPhysicalRange {
11384 heap_range: SecureHeapAndRange,
11385 responder: SecureMemDeleteSecureHeapPhysicalRangeResponder,
11386 },
11387 /// This request from sysmem to the securemem driver conveys a physical
11388 /// range to modify and its new base and length, for a heap whose physical
11389 /// range(s) are set up via sysmem.
11390 ///
11391 /// Only sysmem can call this because only sysmem is handed the client end
11392 /// of a FIDL channel serving this protocol, via RegisterSecureMem(). The
11393 /// securemem driver is the server end of this protocol.
11394 ///
11395 /// The securemem driver must configure the range to cover only the new
11396 /// offsets before responding to this message with success.
11397 ///
11398 /// On failure, the securemem driver must ensure the range was not changed.
11399 ///
11400 /// Sysmem must not call this if dynamic_protection_ranges false. Sysmem
11401 /// must not call this if !is_mod_protected_range_available.
11402 ///
11403 /// If dynamic_protection_ranges is true, sysmem can call this repeatedly,
11404 /// on various ranges that exist at the time of the call.
11405 ///
11406 /// The range must only be modified at one end or the other, but not both.
11407 /// If the range is getting shorter, and the un-covered blocks are not
11408 /// covered by other active ranges, any ongoing DMA to the entire range
11409 /// that's geting shorter may fail in a way that disrupts the entire system
11410 /// (bus lockup or similar), so the caller must ensure that no DMA is
11411 /// ongoing to any portion of a range that is getting shorter, unless the
11412 /// blocks being un-covered by the modification to this range are all
11413 /// covered by other active ranges, in which case no disruption to ongoing
11414 /// DMA will occur.
11415 ///
11416 /// If a range is modified to become <= zero length, the range is deleted.
11417 ///
11418 /// Errors:
11419 /// * ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
11420 /// * ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range
11421 /// that doesn't conform to protected_range_granularity, or old_range
11422 /// and new_range differ in both begin and end (disallowed).
11423 /// * ZX_ERR_INTERNAL - generic internal error (such as in communication
11424 /// with TEE which doesn't generate zx_status_t errors).
11425 /// * ZX_ERR_NOT_FOUND - the specified range is not found.
11426 /// * other errors are possible, such as from communication failures or
11427 /// server propagation of zx_status_t failures.
11428 ModifySecureHeapPhysicalRange {
11429 range_modification: SecureHeapAndRangeModification,
11430 responder: SecureMemModifySecureHeapPhysicalRangeResponder,
11431 },
11432 /// Zero a sub-range of a currently-existing physical range added via
11433 /// AddSecureHeapPhysicalRange(). The sub-range must be fully covered by
11434 /// exactly one physical range, and must not overlap with any other
11435 /// physical range.
11436 ///
11437 /// is_covering_range_explicit - When true, the covering range must be one
11438 /// of the ranges explicitly created via AddSecureHeapPhysicalRange(),
11439 /// possibly modified since. When false, the covering range must not
11440 /// be one of the ranges explicitly created via
11441 /// AddSecureHeapPhysicalRange(), but the covering range must exist as
11442 /// a covering range not created via AddSecureHeapPhysicalRange(). The
11443 /// covering range is typically the entire physical range (or a range
11444 /// which covers even more) of a heap configured by the TEE and whose
11445 /// configuration is conveyed to sysmem via GetPhysicalSecureHeaps().
11446 ///
11447 /// Ongoing DMA is not disrupted by this request.
11448 ZeroSubRange {
11449 is_covering_range_explicit: bool,
11450 heap_range: SecureHeapAndRange,
11451 responder: SecureMemZeroSubRangeResponder,
11452 },
11453}
11454
11455impl SecureMemRequest {
11456 #[allow(irrefutable_let_patterns)]
11457 pub fn into_get_physical_secure_heaps(
11458 self,
11459 ) -> Option<(SecureMemGetPhysicalSecureHeapsResponder)> {
11460 if let SecureMemRequest::GetPhysicalSecureHeaps { responder } = self {
11461 Some((responder))
11462 } else {
11463 None
11464 }
11465 }
11466
11467 #[allow(irrefutable_let_patterns)]
11468 pub fn into_get_physical_secure_heap_properties(
11469 self,
11470 ) -> Option<(SecureHeapAndRange, SecureMemGetPhysicalSecureHeapPropertiesResponder)> {
11471 if let SecureMemRequest::GetPhysicalSecureHeapProperties { entire_heap, responder } = self {
11472 Some((entire_heap, responder))
11473 } else {
11474 None
11475 }
11476 }
11477
11478 #[allow(irrefutable_let_patterns)]
11479 pub fn into_add_secure_heap_physical_range(
11480 self,
11481 ) -> Option<(SecureHeapAndRange, SecureMemAddSecureHeapPhysicalRangeResponder)> {
11482 if let SecureMemRequest::AddSecureHeapPhysicalRange { heap_range, responder } = self {
11483 Some((heap_range, responder))
11484 } else {
11485 None
11486 }
11487 }
11488
11489 #[allow(irrefutable_let_patterns)]
11490 pub fn into_delete_secure_heap_physical_range(
11491 self,
11492 ) -> Option<(SecureHeapAndRange, SecureMemDeleteSecureHeapPhysicalRangeResponder)> {
11493 if let SecureMemRequest::DeleteSecureHeapPhysicalRange { heap_range, responder } = self {
11494 Some((heap_range, responder))
11495 } else {
11496 None
11497 }
11498 }
11499
11500 #[allow(irrefutable_let_patterns)]
11501 pub fn into_modify_secure_heap_physical_range(
11502 self,
11503 ) -> Option<(SecureHeapAndRangeModification, SecureMemModifySecureHeapPhysicalRangeResponder)>
11504 {
11505 if let SecureMemRequest::ModifySecureHeapPhysicalRange { range_modification, responder } =
11506 self
11507 {
11508 Some((range_modification, responder))
11509 } else {
11510 None
11511 }
11512 }
11513
11514 #[allow(irrefutable_let_patterns)]
11515 pub fn into_zero_sub_range(
11516 self,
11517 ) -> Option<(bool, SecureHeapAndRange, SecureMemZeroSubRangeResponder)> {
11518 if let SecureMemRequest::ZeroSubRange {
11519 is_covering_range_explicit,
11520 heap_range,
11521 responder,
11522 } = self
11523 {
11524 Some((is_covering_range_explicit, heap_range, responder))
11525 } else {
11526 None
11527 }
11528 }
11529
11530 /// Name of the method defined in FIDL
11531 pub fn method_name(&self) -> &'static str {
11532 match *self {
11533 SecureMemRequest::GetPhysicalSecureHeaps { .. } => "get_physical_secure_heaps",
11534 SecureMemRequest::GetPhysicalSecureHeapProperties { .. } => {
11535 "get_physical_secure_heap_properties"
11536 }
11537 SecureMemRequest::AddSecureHeapPhysicalRange { .. } => "add_secure_heap_physical_range",
11538 SecureMemRequest::DeleteSecureHeapPhysicalRange { .. } => {
11539 "delete_secure_heap_physical_range"
11540 }
11541 SecureMemRequest::ModifySecureHeapPhysicalRange { .. } => {
11542 "modify_secure_heap_physical_range"
11543 }
11544 SecureMemRequest::ZeroSubRange { .. } => "zero_sub_range",
11545 }
11546 }
11547}
11548
11549#[derive(Debug, Clone)]
11550pub struct SecureMemControlHandle {
11551 inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
11552}
11553
11554impl SecureMemControlHandle {
11555 pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
11556 self.inner.shutdown_with_epitaph(status.into())
11557 }
11558}
11559
11560impl fidl::endpoints::ControlHandle for SecureMemControlHandle {
11561 fn shutdown(&self) {
11562 self.inner.shutdown()
11563 }
11564
11565 fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
11566 self.inner.shutdown_with_epitaph(status)
11567 }
11568
11569 fn is_closed(&self) -> bool {
11570 self.inner.channel().is_closed()
11571 }
11572 fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
11573 self.inner.channel().on_closed()
11574 }
11575
11576 #[cfg(target_os = "fuchsia")]
11577 fn signal_peer(
11578 &self,
11579 clear_mask: zx::Signals,
11580 set_mask: zx::Signals,
11581 ) -> Result<(), zx_status::Status> {
11582 use fidl::Peered;
11583 self.inner.channel().signal_peer(clear_mask, set_mask)
11584 }
11585}
11586
11587impl SecureMemControlHandle {}
11588
11589#[must_use = "FIDL methods require a response to be sent"]
11590#[derive(Debug)]
11591pub struct SecureMemGetPhysicalSecureHeapsResponder {
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 SecureMemGetPhysicalSecureHeapsResponder {
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 SecureMemGetPhysicalSecureHeapsResponder {
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 SecureMemGetPhysicalSecureHeapsResponder {
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<&SecureHeapsAndRanges, 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<&SecureHeapsAndRanges, 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<&SecureHeapsAndRanges, i32>) -> Result<(), fidl::Error> {
11646 self.control_handle.inner.send::<fidl::encoding::ResultType<
11647 SecureMemGetPhysicalSecureHeapsResponse,
11648 i32,
11649 >>(
11650 result.map(|heaps| (heaps,)),
11651 self.tx_id,
11652 0x782319d6ce7fa05,
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 SecureMemGetPhysicalSecureHeapPropertiesResponder {
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 SecureMemGetPhysicalSecureHeapPropertiesResponder {
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 SecureMemGetPhysicalSecureHeapPropertiesResponder {
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 SecureMemGetPhysicalSecureHeapPropertiesResponder {
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<&SecureHeapProperties, 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(
11706 self,
11707 mut result: Result<&SecureHeapProperties, i32>,
11708 ) -> Result<(), fidl::Error> {
11709 let _result = self.send_raw(result);
11710 self.drop_without_shutdown();
11711 _result
11712 }
11713
11714 fn send_raw(&self, mut result: Result<&SecureHeapProperties, i32>) -> Result<(), fidl::Error> {
11715 self.control_handle.inner.send::<fidl::encoding::ResultType<
11716 SecureMemGetPhysicalSecureHeapPropertiesResponse,
11717 i32,
11718 >>(
11719 result.map(|properties| (properties,)),
11720 self.tx_id,
11721 0x26404e23f1271214,
11722 fidl::encoding::DynamicFlags::empty(),
11723 )
11724 }
11725}
11726
11727#[must_use = "FIDL methods require a response to be sent"]
11728#[derive(Debug)]
11729pub struct SecureMemAddSecureHeapPhysicalRangeResponder {
11730 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11731 tx_id: u32,
11732}
11733
11734/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11735/// if the responder is dropped without sending a response, so that the client
11736/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11737impl std::ops::Drop for SecureMemAddSecureHeapPhysicalRangeResponder {
11738 fn drop(&mut self) {
11739 self.control_handle.shutdown();
11740 // Safety: drops once, never accessed again
11741 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11742 }
11743}
11744
11745impl fidl::endpoints::Responder for SecureMemAddSecureHeapPhysicalRangeResponder {
11746 type ControlHandle = SecureMemControlHandle;
11747
11748 fn control_handle(&self) -> &SecureMemControlHandle {
11749 &self.control_handle
11750 }
11751
11752 fn drop_without_shutdown(mut self) {
11753 // Safety: drops once, never accessed again due to mem::forget
11754 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11755 // Prevent Drop from running (which would shut down the channel)
11756 std::mem::forget(self);
11757 }
11758}
11759
11760impl SecureMemAddSecureHeapPhysicalRangeResponder {
11761 /// Sends a response to the FIDL transaction.
11762 ///
11763 /// Sets the channel to shutdown if an error occurs.
11764 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11765 let _result = self.send_raw(result);
11766 if _result.is_err() {
11767 self.control_handle.shutdown();
11768 }
11769 self.drop_without_shutdown();
11770 _result
11771 }
11772
11773 /// Similar to "send" but does not shutdown the channel if an error occurs.
11774 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11775 let _result = self.send_raw(result);
11776 self.drop_without_shutdown();
11777 _result
11778 }
11779
11780 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11781 self.control_handle
11782 .inner
11783 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11784 result,
11785 self.tx_id,
11786 0x1ca1abcee8a0b33e,
11787 fidl::encoding::DynamicFlags::empty(),
11788 )
11789 }
11790}
11791
11792#[must_use = "FIDL methods require a response to be sent"]
11793#[derive(Debug)]
11794pub struct SecureMemDeleteSecureHeapPhysicalRangeResponder {
11795 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11796 tx_id: u32,
11797}
11798
11799/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11800/// if the responder is dropped without sending a response, so that the client
11801/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11802impl std::ops::Drop for SecureMemDeleteSecureHeapPhysicalRangeResponder {
11803 fn drop(&mut self) {
11804 self.control_handle.shutdown();
11805 // Safety: drops once, never accessed again
11806 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11807 }
11808}
11809
11810impl fidl::endpoints::Responder for SecureMemDeleteSecureHeapPhysicalRangeResponder {
11811 type ControlHandle = SecureMemControlHandle;
11812
11813 fn control_handle(&self) -> &SecureMemControlHandle {
11814 &self.control_handle
11815 }
11816
11817 fn drop_without_shutdown(mut self) {
11818 // Safety: drops once, never accessed again due to mem::forget
11819 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11820 // Prevent Drop from running (which would shut down the channel)
11821 std::mem::forget(self);
11822 }
11823}
11824
11825impl SecureMemDeleteSecureHeapPhysicalRangeResponder {
11826 /// Sends a response to the FIDL transaction.
11827 ///
11828 /// Sets the channel to shutdown if an error occurs.
11829 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11830 let _result = self.send_raw(result);
11831 if _result.is_err() {
11832 self.control_handle.shutdown();
11833 }
11834 self.drop_without_shutdown();
11835 _result
11836 }
11837
11838 /// Similar to "send" but does not shutdown the channel if an error occurs.
11839 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11840 let _result = self.send_raw(result);
11841 self.drop_without_shutdown();
11842 _result
11843 }
11844
11845 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11846 self.control_handle
11847 .inner
11848 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11849 result,
11850 self.tx_id,
11851 0x728a953e56df92ee,
11852 fidl::encoding::DynamicFlags::empty(),
11853 )
11854 }
11855}
11856
11857#[must_use = "FIDL methods require a response to be sent"]
11858#[derive(Debug)]
11859pub struct SecureMemModifySecureHeapPhysicalRangeResponder {
11860 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11861 tx_id: u32,
11862}
11863
11864/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11865/// if the responder is dropped without sending a response, so that the client
11866/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11867impl std::ops::Drop for SecureMemModifySecureHeapPhysicalRangeResponder {
11868 fn drop(&mut self) {
11869 self.control_handle.shutdown();
11870 // Safety: drops once, never accessed again
11871 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11872 }
11873}
11874
11875impl fidl::endpoints::Responder for SecureMemModifySecureHeapPhysicalRangeResponder {
11876 type ControlHandle = SecureMemControlHandle;
11877
11878 fn control_handle(&self) -> &SecureMemControlHandle {
11879 &self.control_handle
11880 }
11881
11882 fn drop_without_shutdown(mut self) {
11883 // Safety: drops once, never accessed again due to mem::forget
11884 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11885 // Prevent Drop from running (which would shut down the channel)
11886 std::mem::forget(self);
11887 }
11888}
11889
11890impl SecureMemModifySecureHeapPhysicalRangeResponder {
11891 /// Sends a response to the FIDL transaction.
11892 ///
11893 /// Sets the channel to shutdown if an error occurs.
11894 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11895 let _result = self.send_raw(result);
11896 if _result.is_err() {
11897 self.control_handle.shutdown();
11898 }
11899 self.drop_without_shutdown();
11900 _result
11901 }
11902
11903 /// Similar to "send" but does not shutdown the channel if an error occurs.
11904 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11905 let _result = self.send_raw(result);
11906 self.drop_without_shutdown();
11907 _result
11908 }
11909
11910 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11911 self.control_handle
11912 .inner
11913 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11914 result,
11915 self.tx_id,
11916 0x154fbfa3646a890d,
11917 fidl::encoding::DynamicFlags::empty(),
11918 )
11919 }
11920}
11921
11922#[must_use = "FIDL methods require a response to be sent"]
11923#[derive(Debug)]
11924pub struct SecureMemZeroSubRangeResponder {
11925 control_handle: std::mem::ManuallyDrop<SecureMemControlHandle>,
11926 tx_id: u32,
11927}
11928
11929/// Set the the channel to be shutdown (see [`SecureMemControlHandle::shutdown`])
11930/// if the responder is dropped without sending a response, so that the client
11931/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
11932impl std::ops::Drop for SecureMemZeroSubRangeResponder {
11933 fn drop(&mut self) {
11934 self.control_handle.shutdown();
11935 // Safety: drops once, never accessed again
11936 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11937 }
11938}
11939
11940impl fidl::endpoints::Responder for SecureMemZeroSubRangeResponder {
11941 type ControlHandle = SecureMemControlHandle;
11942
11943 fn control_handle(&self) -> &SecureMemControlHandle {
11944 &self.control_handle
11945 }
11946
11947 fn drop_without_shutdown(mut self) {
11948 // Safety: drops once, never accessed again due to mem::forget
11949 unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
11950 // Prevent Drop from running (which would shut down the channel)
11951 std::mem::forget(self);
11952 }
11953}
11954
11955impl SecureMemZeroSubRangeResponder {
11956 /// Sends a response to the FIDL transaction.
11957 ///
11958 /// Sets the channel to shutdown if an error occurs.
11959 pub fn send(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11960 let _result = self.send_raw(result);
11961 if _result.is_err() {
11962 self.control_handle.shutdown();
11963 }
11964 self.drop_without_shutdown();
11965 _result
11966 }
11967
11968 /// Similar to "send" but does not shutdown the channel if an error occurs.
11969 pub fn send_no_shutdown_on_err(self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11970 let _result = self.send_raw(result);
11971 self.drop_without_shutdown();
11972 _result
11973 }
11974
11975 fn send_raw(&self, mut result: Result<(), i32>) -> Result<(), fidl::Error> {
11976 self.control_handle
11977 .inner
11978 .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, i32>>(
11979 result,
11980 self.tx_id,
11981 0x7480f72bb5bc7e5b,
11982 fidl::encoding::DynamicFlags::empty(),
11983 )
11984 }
11985}
11986
11987mod internal {
11988 use super::*;
11989
11990 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateNonSharedCollectionRequest {
11991 type Borrowed<'a> = &'a mut Self;
11992 fn take_or_borrow<'a>(
11993 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
11994 ) -> Self::Borrowed<'a> {
11995 value
11996 }
11997 }
11998
11999 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateNonSharedCollectionRequest {
12000 type Owned = Self;
12001
12002 #[inline(always)]
12003 fn inline_align(_context: fidl::encoding::Context) -> usize {
12004 4
12005 }
12006
12007 #[inline(always)]
12008 fn inline_size(_context: fidl::encoding::Context) -> usize {
12009 4
12010 }
12011 }
12012
12013 unsafe impl
12014 fidl::encoding::Encode<
12015 AllocatorAllocateNonSharedCollectionRequest,
12016 fidl::encoding::DefaultFuchsiaResourceDialect,
12017 > for &mut AllocatorAllocateNonSharedCollectionRequest
12018 {
12019 #[inline]
12020 unsafe fn encode(
12021 self,
12022 encoder: &mut fidl::encoding::Encoder<
12023 '_,
12024 fidl::encoding::DefaultFuchsiaResourceDialect,
12025 >,
12026 offset: usize,
12027 _depth: fidl::encoding::Depth,
12028 ) -> fidl::Result<()> {
12029 encoder.debug_check_bounds::<AllocatorAllocateNonSharedCollectionRequest>(offset);
12030 // Delegate to tuple encoding.
12031 fidl::encoding::Encode::<AllocatorAllocateNonSharedCollectionRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
12032 (
12033 <fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.collection_request),
12034 ),
12035 encoder, offset, _depth
12036 )
12037 }
12038 }
12039 unsafe impl<
12040 T0: fidl::encoding::Encode<
12041 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12042 fidl::encoding::DefaultFuchsiaResourceDialect,
12043 >,
12044 >
12045 fidl::encoding::Encode<
12046 AllocatorAllocateNonSharedCollectionRequest,
12047 fidl::encoding::DefaultFuchsiaResourceDialect,
12048 > for (T0,)
12049 {
12050 #[inline]
12051 unsafe fn encode(
12052 self,
12053 encoder: &mut fidl::encoding::Encoder<
12054 '_,
12055 fidl::encoding::DefaultFuchsiaResourceDialect,
12056 >,
12057 offset: usize,
12058 depth: fidl::encoding::Depth,
12059 ) -> fidl::Result<()> {
12060 encoder.debug_check_bounds::<AllocatorAllocateNonSharedCollectionRequest>(offset);
12061 // Zero out padding regions. There's no need to apply masks
12062 // because the unmasked parts will be overwritten by fields.
12063 // Write the fields.
12064 self.0.encode(encoder, offset + 0, depth)?;
12065 Ok(())
12066 }
12067 }
12068
12069 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12070 for AllocatorAllocateNonSharedCollectionRequest
12071 {
12072 #[inline(always)]
12073 fn new_empty() -> Self {
12074 Self {
12075 collection_request: fidl::new_empty!(
12076 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12077 fidl::encoding::DefaultFuchsiaResourceDialect
12078 ),
12079 }
12080 }
12081
12082 #[inline]
12083 unsafe fn decode(
12084 &mut self,
12085 decoder: &mut fidl::encoding::Decoder<
12086 '_,
12087 fidl::encoding::DefaultFuchsiaResourceDialect,
12088 >,
12089 offset: usize,
12090 _depth: fidl::encoding::Depth,
12091 ) -> fidl::Result<()> {
12092 decoder.debug_check_bounds::<Self>(offset);
12093 // Verify that padding bytes are zero.
12094 fidl::decode!(
12095 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12096 fidl::encoding::DefaultFuchsiaResourceDialect,
12097 &mut self.collection_request,
12098 decoder,
12099 offset + 0,
12100 _depth
12101 )?;
12102 Ok(())
12103 }
12104 }
12105
12106 impl fidl::encoding::ResourceTypeMarker for AllocatorAllocateSharedCollectionRequest {
12107 type Borrowed<'a> = &'a mut Self;
12108 fn take_or_borrow<'a>(
12109 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12110 ) -> Self::Borrowed<'a> {
12111 value
12112 }
12113 }
12114
12115 unsafe impl fidl::encoding::TypeMarker for AllocatorAllocateSharedCollectionRequest {
12116 type Owned = Self;
12117
12118 #[inline(always)]
12119 fn inline_align(_context: fidl::encoding::Context) -> usize {
12120 4
12121 }
12122
12123 #[inline(always)]
12124 fn inline_size(_context: fidl::encoding::Context) -> usize {
12125 4
12126 }
12127 }
12128
12129 unsafe impl
12130 fidl::encoding::Encode<
12131 AllocatorAllocateSharedCollectionRequest,
12132 fidl::encoding::DefaultFuchsiaResourceDialect,
12133 > for &mut AllocatorAllocateSharedCollectionRequest
12134 {
12135 #[inline]
12136 unsafe fn encode(
12137 self,
12138 encoder: &mut fidl::encoding::Encoder<
12139 '_,
12140 fidl::encoding::DefaultFuchsiaResourceDialect,
12141 >,
12142 offset: usize,
12143 _depth: fidl::encoding::Depth,
12144 ) -> fidl::Result<()> {
12145 encoder.debug_check_bounds::<AllocatorAllocateSharedCollectionRequest>(offset);
12146 // Delegate to tuple encoding.
12147 fidl::encoding::Encode::<
12148 AllocatorAllocateSharedCollectionRequest,
12149 fidl::encoding::DefaultFuchsiaResourceDialect,
12150 >::encode(
12151 (
12152 <fidl::encoding::Endpoint<
12153 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12154 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12155 &mut self.token_request,
12156 ),
12157 ),
12158 encoder,
12159 offset,
12160 _depth,
12161 )
12162 }
12163 }
12164 unsafe impl<
12165 T0: fidl::encoding::Encode<
12166 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12167 fidl::encoding::DefaultFuchsiaResourceDialect,
12168 >,
12169 >
12170 fidl::encoding::Encode<
12171 AllocatorAllocateSharedCollectionRequest,
12172 fidl::encoding::DefaultFuchsiaResourceDialect,
12173 > for (T0,)
12174 {
12175 #[inline]
12176 unsafe fn encode(
12177 self,
12178 encoder: &mut fidl::encoding::Encoder<
12179 '_,
12180 fidl::encoding::DefaultFuchsiaResourceDialect,
12181 >,
12182 offset: usize,
12183 depth: fidl::encoding::Depth,
12184 ) -> fidl::Result<()> {
12185 encoder.debug_check_bounds::<AllocatorAllocateSharedCollectionRequest>(offset);
12186 // Zero out padding regions. There's no need to apply masks
12187 // because the unmasked parts will be overwritten by fields.
12188 // Write the fields.
12189 self.0.encode(encoder, offset + 0, depth)?;
12190 Ok(())
12191 }
12192 }
12193
12194 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12195 for AllocatorAllocateSharedCollectionRequest
12196 {
12197 #[inline(always)]
12198 fn new_empty() -> Self {
12199 Self {
12200 token_request: fidl::new_empty!(
12201 fidl::encoding::Endpoint<
12202 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12203 >,
12204 fidl::encoding::DefaultFuchsiaResourceDialect
12205 ),
12206 }
12207 }
12208
12209 #[inline]
12210 unsafe fn decode(
12211 &mut self,
12212 decoder: &mut fidl::encoding::Decoder<
12213 '_,
12214 fidl::encoding::DefaultFuchsiaResourceDialect,
12215 >,
12216 offset: usize,
12217 _depth: fidl::encoding::Depth,
12218 ) -> fidl::Result<()> {
12219 decoder.debug_check_bounds::<Self>(offset);
12220 // Verify that padding bytes are zero.
12221 fidl::decode!(
12222 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12223 fidl::encoding::DefaultFuchsiaResourceDialect,
12224 &mut self.token_request,
12225 decoder,
12226 offset + 0,
12227 _depth
12228 )?;
12229 Ok(())
12230 }
12231 }
12232
12233 impl fidl::encoding::ResourceTypeMarker for AllocatorBindSharedCollectionRequest {
12234 type Borrowed<'a> = &'a mut Self;
12235 fn take_or_borrow<'a>(
12236 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12237 ) -> Self::Borrowed<'a> {
12238 value
12239 }
12240 }
12241
12242 unsafe impl fidl::encoding::TypeMarker for AllocatorBindSharedCollectionRequest {
12243 type Owned = Self;
12244
12245 #[inline(always)]
12246 fn inline_align(_context: fidl::encoding::Context) -> usize {
12247 4
12248 }
12249
12250 #[inline(always)]
12251 fn inline_size(_context: fidl::encoding::Context) -> usize {
12252 8
12253 }
12254 }
12255
12256 unsafe impl
12257 fidl::encoding::Encode<
12258 AllocatorBindSharedCollectionRequest,
12259 fidl::encoding::DefaultFuchsiaResourceDialect,
12260 > for &mut AllocatorBindSharedCollectionRequest
12261 {
12262 #[inline]
12263 unsafe fn encode(
12264 self,
12265 encoder: &mut fidl::encoding::Encoder<
12266 '_,
12267 fidl::encoding::DefaultFuchsiaResourceDialect,
12268 >,
12269 offset: usize,
12270 _depth: fidl::encoding::Depth,
12271 ) -> fidl::Result<()> {
12272 encoder.debug_check_bounds::<AllocatorBindSharedCollectionRequest>(offset);
12273 // Delegate to tuple encoding.
12274 fidl::encoding::Encode::<AllocatorBindSharedCollectionRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
12275 (
12276 <fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.token),
12277 <fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffer_collection_request),
12278 ),
12279 encoder, offset, _depth
12280 )
12281 }
12282 }
12283 unsafe impl<
12284 T0: fidl::encoding::Encode<
12285 fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
12286 fidl::encoding::DefaultFuchsiaResourceDialect,
12287 >,
12288 T1: fidl::encoding::Encode<
12289 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12290 fidl::encoding::DefaultFuchsiaResourceDialect,
12291 >,
12292 >
12293 fidl::encoding::Encode<
12294 AllocatorBindSharedCollectionRequest,
12295 fidl::encoding::DefaultFuchsiaResourceDialect,
12296 > for (T0, T1)
12297 {
12298 #[inline]
12299 unsafe fn encode(
12300 self,
12301 encoder: &mut fidl::encoding::Encoder<
12302 '_,
12303 fidl::encoding::DefaultFuchsiaResourceDialect,
12304 >,
12305 offset: usize,
12306 depth: fidl::encoding::Depth,
12307 ) -> fidl::Result<()> {
12308 encoder.debug_check_bounds::<AllocatorBindSharedCollectionRequest>(offset);
12309 // Zero out padding regions. There's no need to apply masks
12310 // because the unmasked parts will be overwritten by fields.
12311 // Write the fields.
12312 self.0.encode(encoder, offset + 0, depth)?;
12313 self.1.encode(encoder, offset + 4, depth)?;
12314 Ok(())
12315 }
12316 }
12317
12318 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12319 for AllocatorBindSharedCollectionRequest
12320 {
12321 #[inline(always)]
12322 fn new_empty() -> Self {
12323 Self {
12324 token: fidl::new_empty!(
12325 fidl::encoding::Endpoint<
12326 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
12327 >,
12328 fidl::encoding::DefaultFuchsiaResourceDialect
12329 ),
12330 buffer_collection_request: fidl::new_empty!(
12331 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12332 fidl::encoding::DefaultFuchsiaResourceDialect
12333 ),
12334 }
12335 }
12336
12337 #[inline]
12338 unsafe fn decode(
12339 &mut self,
12340 decoder: &mut fidl::encoding::Decoder<
12341 '_,
12342 fidl::encoding::DefaultFuchsiaResourceDialect,
12343 >,
12344 offset: usize,
12345 _depth: fidl::encoding::Depth,
12346 ) -> fidl::Result<()> {
12347 decoder.debug_check_bounds::<Self>(offset);
12348 // Verify that padding bytes are zero.
12349 fidl::decode!(
12350 fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>>,
12351 fidl::encoding::DefaultFuchsiaResourceDialect,
12352 &mut self.token,
12353 decoder,
12354 offset + 0,
12355 _depth
12356 )?;
12357 fidl::decode!(
12358 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionMarker>>,
12359 fidl::encoding::DefaultFuchsiaResourceDialect,
12360 &mut self.buffer_collection_request,
12361 decoder,
12362 offset + 4,
12363 _depth
12364 )?;
12365 Ok(())
12366 }
12367 }
12368
12369 impl fidl::encoding::ResourceTypeMarker for AllocatorConnectToSysmem2AllocatorRequest {
12370 type Borrowed<'a> = &'a mut Self;
12371 fn take_or_borrow<'a>(
12372 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12373 ) -> Self::Borrowed<'a> {
12374 value
12375 }
12376 }
12377
12378 unsafe impl fidl::encoding::TypeMarker for AllocatorConnectToSysmem2AllocatorRequest {
12379 type Owned = Self;
12380
12381 #[inline(always)]
12382 fn inline_align(_context: fidl::encoding::Context) -> usize {
12383 4
12384 }
12385
12386 #[inline(always)]
12387 fn inline_size(_context: fidl::encoding::Context) -> usize {
12388 4
12389 }
12390 }
12391
12392 unsafe impl
12393 fidl::encoding::Encode<
12394 AllocatorConnectToSysmem2AllocatorRequest,
12395 fidl::encoding::DefaultFuchsiaResourceDialect,
12396 > for &mut AllocatorConnectToSysmem2AllocatorRequest
12397 {
12398 #[inline]
12399 unsafe fn encode(
12400 self,
12401 encoder: &mut fidl::encoding::Encoder<
12402 '_,
12403 fidl::encoding::DefaultFuchsiaResourceDialect,
12404 >,
12405 offset: usize,
12406 _depth: fidl::encoding::Depth,
12407 ) -> fidl::Result<()> {
12408 encoder.debug_check_bounds::<AllocatorConnectToSysmem2AllocatorRequest>(offset);
12409 // Delegate to tuple encoding.
12410 fidl::encoding::Encode::<
12411 AllocatorConnectToSysmem2AllocatorRequest,
12412 fidl::encoding::DefaultFuchsiaResourceDialect,
12413 >::encode(
12414 (<fidl::encoding::Endpoint<
12415 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12416 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12417 &mut self.allocator_request,
12418 ),),
12419 encoder,
12420 offset,
12421 _depth,
12422 )
12423 }
12424 }
12425 unsafe impl<
12426 T0: fidl::encoding::Encode<
12427 fidl::encoding::Endpoint<
12428 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12429 >,
12430 fidl::encoding::DefaultFuchsiaResourceDialect,
12431 >,
12432 >
12433 fidl::encoding::Encode<
12434 AllocatorConnectToSysmem2AllocatorRequest,
12435 fidl::encoding::DefaultFuchsiaResourceDialect,
12436 > for (T0,)
12437 {
12438 #[inline]
12439 unsafe fn encode(
12440 self,
12441 encoder: &mut fidl::encoding::Encoder<
12442 '_,
12443 fidl::encoding::DefaultFuchsiaResourceDialect,
12444 >,
12445 offset: usize,
12446 depth: fidl::encoding::Depth,
12447 ) -> fidl::Result<()> {
12448 encoder.debug_check_bounds::<AllocatorConnectToSysmem2AllocatorRequest>(offset);
12449 // Zero out padding regions. There's no need to apply masks
12450 // because the unmasked parts will be overwritten by fields.
12451 // Write the fields.
12452 self.0.encode(encoder, offset + 0, depth)?;
12453 Ok(())
12454 }
12455 }
12456
12457 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12458 for AllocatorConnectToSysmem2AllocatorRequest
12459 {
12460 #[inline(always)]
12461 fn new_empty() -> Self {
12462 Self {
12463 allocator_request: fidl::new_empty!(
12464 fidl::encoding::Endpoint<
12465 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12466 >,
12467 fidl::encoding::DefaultFuchsiaResourceDialect
12468 ),
12469 }
12470 }
12471
12472 #[inline]
12473 unsafe fn decode(
12474 &mut self,
12475 decoder: &mut fidl::encoding::Decoder<
12476 '_,
12477 fidl::encoding::DefaultFuchsiaResourceDialect,
12478 >,
12479 offset: usize,
12480 _depth: fidl::encoding::Depth,
12481 ) -> fidl::Result<()> {
12482 decoder.debug_check_bounds::<Self>(offset);
12483 // Verify that padding bytes are zero.
12484 fidl::decode!(
12485 fidl::encoding::Endpoint<
12486 fidl::endpoints::ServerEnd<fidl_fuchsia_sysmem2::AllocatorMarker>,
12487 >,
12488 fidl::encoding::DefaultFuchsiaResourceDialect,
12489 &mut self.allocator_request,
12490 decoder,
12491 offset + 0,
12492 _depth
12493 )?;
12494 Ok(())
12495 }
12496 }
12497
12498 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
12499 type Borrowed<'a> = &'a mut Self;
12500 fn take_or_borrow<'a>(
12501 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12502 ) -> Self::Borrowed<'a> {
12503 value
12504 }
12505 }
12506
12507 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachLifetimeTrackingRequest {
12508 type Owned = Self;
12509
12510 #[inline(always)]
12511 fn inline_align(_context: fidl::encoding::Context) -> usize {
12512 4
12513 }
12514
12515 #[inline(always)]
12516 fn inline_size(_context: fidl::encoding::Context) -> usize {
12517 8
12518 }
12519 }
12520
12521 unsafe impl
12522 fidl::encoding::Encode<
12523 BufferCollectionAttachLifetimeTrackingRequest,
12524 fidl::encoding::DefaultFuchsiaResourceDialect,
12525 > for &mut BufferCollectionAttachLifetimeTrackingRequest
12526 {
12527 #[inline]
12528 unsafe fn encode(
12529 self,
12530 encoder: &mut fidl::encoding::Encoder<
12531 '_,
12532 fidl::encoding::DefaultFuchsiaResourceDialect,
12533 >,
12534 offset: usize,
12535 _depth: fidl::encoding::Depth,
12536 ) -> fidl::Result<()> {
12537 encoder.debug_check_bounds::<BufferCollectionAttachLifetimeTrackingRequest>(offset);
12538 // Delegate to tuple encoding.
12539 fidl::encoding::Encode::<
12540 BufferCollectionAttachLifetimeTrackingRequest,
12541 fidl::encoding::DefaultFuchsiaResourceDialect,
12542 >::encode(
12543 (
12544 <fidl::encoding::HandleType<
12545 fidl::EventPair,
12546 { fidl::ObjectType::EVENTPAIR.into_raw() },
12547 2147483648,
12548 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12549 &mut self.server_end
12550 ),
12551 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffers_remaining),
12552 ),
12553 encoder,
12554 offset,
12555 _depth,
12556 )
12557 }
12558 }
12559 unsafe impl<
12560 T0: fidl::encoding::Encode<
12561 fidl::encoding::HandleType<
12562 fidl::EventPair,
12563 { fidl::ObjectType::EVENTPAIR.into_raw() },
12564 2147483648,
12565 >,
12566 fidl::encoding::DefaultFuchsiaResourceDialect,
12567 >,
12568 T1: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12569 >
12570 fidl::encoding::Encode<
12571 BufferCollectionAttachLifetimeTrackingRequest,
12572 fidl::encoding::DefaultFuchsiaResourceDialect,
12573 > for (T0, T1)
12574 {
12575 #[inline]
12576 unsafe fn encode(
12577 self,
12578 encoder: &mut fidl::encoding::Encoder<
12579 '_,
12580 fidl::encoding::DefaultFuchsiaResourceDialect,
12581 >,
12582 offset: usize,
12583 depth: fidl::encoding::Depth,
12584 ) -> fidl::Result<()> {
12585 encoder.debug_check_bounds::<BufferCollectionAttachLifetimeTrackingRequest>(offset);
12586 // Zero out padding regions. There's no need to apply masks
12587 // because the unmasked parts will be overwritten by fields.
12588 // Write the fields.
12589 self.0.encode(encoder, offset + 0, depth)?;
12590 self.1.encode(encoder, offset + 4, depth)?;
12591 Ok(())
12592 }
12593 }
12594
12595 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12596 for BufferCollectionAttachLifetimeTrackingRequest
12597 {
12598 #[inline(always)]
12599 fn new_empty() -> Self {
12600 Self {
12601 server_end: fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
12602 buffers_remaining: fidl::new_empty!(
12603 u32,
12604 fidl::encoding::DefaultFuchsiaResourceDialect
12605 ),
12606 }
12607 }
12608
12609 #[inline]
12610 unsafe fn decode(
12611 &mut self,
12612 decoder: &mut fidl::encoding::Decoder<
12613 '_,
12614 fidl::encoding::DefaultFuchsiaResourceDialect,
12615 >,
12616 offset: usize,
12617 _depth: fidl::encoding::Depth,
12618 ) -> fidl::Result<()> {
12619 decoder.debug_check_bounds::<Self>(offset);
12620 // Verify that padding bytes are zero.
12621 fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.server_end, decoder, offset + 0, _depth)?;
12622 fidl::decode!(
12623 u32,
12624 fidl::encoding::DefaultFuchsiaResourceDialect,
12625 &mut self.buffers_remaining,
12626 decoder,
12627 offset + 4,
12628 _depth
12629 )?;
12630 Ok(())
12631 }
12632 }
12633
12634 impl fidl::encoding::ResourceTypeMarker for BufferCollectionAttachTokenRequest {
12635 type Borrowed<'a> = &'a mut Self;
12636 fn take_or_borrow<'a>(
12637 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12638 ) -> Self::Borrowed<'a> {
12639 value
12640 }
12641 }
12642
12643 unsafe impl fidl::encoding::TypeMarker for BufferCollectionAttachTokenRequest {
12644 type Owned = Self;
12645
12646 #[inline(always)]
12647 fn inline_align(_context: fidl::encoding::Context) -> usize {
12648 4
12649 }
12650
12651 #[inline(always)]
12652 fn inline_size(_context: fidl::encoding::Context) -> usize {
12653 8
12654 }
12655 }
12656
12657 unsafe impl
12658 fidl::encoding::Encode<
12659 BufferCollectionAttachTokenRequest,
12660 fidl::encoding::DefaultFuchsiaResourceDialect,
12661 > for &mut BufferCollectionAttachTokenRequest
12662 {
12663 #[inline]
12664 unsafe fn encode(
12665 self,
12666 encoder: &mut fidl::encoding::Encoder<
12667 '_,
12668 fidl::encoding::DefaultFuchsiaResourceDialect,
12669 >,
12670 offset: usize,
12671 _depth: fidl::encoding::Depth,
12672 ) -> fidl::Result<()> {
12673 encoder.debug_check_bounds::<BufferCollectionAttachTokenRequest>(offset);
12674 // Delegate to tuple encoding.
12675 fidl::encoding::Encode::<
12676 BufferCollectionAttachTokenRequest,
12677 fidl::encoding::DefaultFuchsiaResourceDialect,
12678 >::encode(
12679 (
12680 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.rights_attenuation_mask),
12681 <fidl::encoding::Endpoint<
12682 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12683 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12684 &mut self.token_request,
12685 ),
12686 ),
12687 encoder,
12688 offset,
12689 _depth,
12690 )
12691 }
12692 }
12693 unsafe impl<
12694 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12695 T1: fidl::encoding::Encode<
12696 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12697 fidl::encoding::DefaultFuchsiaResourceDialect,
12698 >,
12699 >
12700 fidl::encoding::Encode<
12701 BufferCollectionAttachTokenRequest,
12702 fidl::encoding::DefaultFuchsiaResourceDialect,
12703 > for (T0, T1)
12704 {
12705 #[inline]
12706 unsafe fn encode(
12707 self,
12708 encoder: &mut fidl::encoding::Encoder<
12709 '_,
12710 fidl::encoding::DefaultFuchsiaResourceDialect,
12711 >,
12712 offset: usize,
12713 depth: fidl::encoding::Depth,
12714 ) -> fidl::Result<()> {
12715 encoder.debug_check_bounds::<BufferCollectionAttachTokenRequest>(offset);
12716 // Zero out padding regions. There's no need to apply masks
12717 // because the unmasked parts will be overwritten by fields.
12718 // Write the fields.
12719 self.0.encode(encoder, offset + 0, depth)?;
12720 self.1.encode(encoder, offset + 4, depth)?;
12721 Ok(())
12722 }
12723 }
12724
12725 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12726 for BufferCollectionAttachTokenRequest
12727 {
12728 #[inline(always)]
12729 fn new_empty() -> Self {
12730 Self {
12731 rights_attenuation_mask: fidl::new_empty!(
12732 u32,
12733 fidl::encoding::DefaultFuchsiaResourceDialect
12734 ),
12735 token_request: fidl::new_empty!(
12736 fidl::encoding::Endpoint<
12737 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
12738 >,
12739 fidl::encoding::DefaultFuchsiaResourceDialect
12740 ),
12741 }
12742 }
12743
12744 #[inline]
12745 unsafe fn decode(
12746 &mut self,
12747 decoder: &mut fidl::encoding::Decoder<
12748 '_,
12749 fidl::encoding::DefaultFuchsiaResourceDialect,
12750 >,
12751 offset: usize,
12752 _depth: fidl::encoding::Depth,
12753 ) -> fidl::Result<()> {
12754 decoder.debug_check_bounds::<Self>(offset);
12755 // Verify that padding bytes are zero.
12756 fidl::decode!(
12757 u32,
12758 fidl::encoding::DefaultFuchsiaResourceDialect,
12759 &mut self.rights_attenuation_mask,
12760 decoder,
12761 offset + 0,
12762 _depth
12763 )?;
12764 fidl::decode!(
12765 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
12766 fidl::encoding::DefaultFuchsiaResourceDialect,
12767 &mut self.token_request,
12768 decoder,
12769 offset + 4,
12770 _depth
12771 )?;
12772 Ok(())
12773 }
12774 }
12775
12776 impl fidl::encoding::ResourceTypeMarker for BufferCollectionInfo {
12777 type Borrowed<'a> = &'a mut Self;
12778 fn take_or_borrow<'a>(
12779 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12780 ) -> Self::Borrowed<'a> {
12781 value
12782 }
12783 }
12784
12785 unsafe impl fidl::encoding::TypeMarker for BufferCollectionInfo {
12786 type Owned = Self;
12787
12788 #[inline(always)]
12789 fn inline_align(_context: fidl::encoding::Context) -> usize {
12790 8
12791 }
12792
12793 #[inline(always)]
12794 fn inline_size(_context: fidl::encoding::Context) -> usize {
12795 352
12796 }
12797 }
12798
12799 unsafe impl
12800 fidl::encoding::Encode<BufferCollectionInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
12801 for &mut BufferCollectionInfo
12802 {
12803 #[inline]
12804 unsafe fn encode(
12805 self,
12806 encoder: &mut fidl::encoding::Encoder<
12807 '_,
12808 fidl::encoding::DefaultFuchsiaResourceDialect,
12809 >,
12810 offset: usize,
12811 _depth: fidl::encoding::Depth,
12812 ) -> fidl::Result<()> {
12813 encoder.debug_check_bounds::<BufferCollectionInfo>(offset);
12814 // Delegate to tuple encoding.
12815 fidl::encoding::Encode::<
12816 BufferCollectionInfo,
12817 fidl::encoding::DefaultFuchsiaResourceDialect,
12818 >::encode(
12819 (
12820 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffer_count),
12821 <BufferFormat as fidl::encoding::ValueTypeMarker>::borrow(&self.format),
12822 <fidl::encoding::Array<
12823 fidl::encoding::Optional<
12824 fidl::encoding::HandleType<
12825 fidl::Vmo,
12826 { fidl::ObjectType::VMO.into_raw() },
12827 2147483648,
12828 >,
12829 >,
12830 64,
12831 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
12832 &mut self.vmos
12833 ),
12834 <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.vmo_size),
12835 ),
12836 encoder,
12837 offset,
12838 _depth,
12839 )
12840 }
12841 }
12842 unsafe impl<
12843 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
12844 T1: fidl::encoding::Encode<BufferFormat, fidl::encoding::DefaultFuchsiaResourceDialect>,
12845 T2: fidl::encoding::Encode<
12846 fidl::encoding::Array<
12847 fidl::encoding::Optional<
12848 fidl::encoding::HandleType<
12849 fidl::Vmo,
12850 { fidl::ObjectType::VMO.into_raw() },
12851 2147483648,
12852 >,
12853 >,
12854 64,
12855 >,
12856 fidl::encoding::DefaultFuchsiaResourceDialect,
12857 >,
12858 T3: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
12859 >
12860 fidl::encoding::Encode<BufferCollectionInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
12861 for (T0, T1, T2, T3)
12862 {
12863 #[inline]
12864 unsafe fn encode(
12865 self,
12866 encoder: &mut fidl::encoding::Encoder<
12867 '_,
12868 fidl::encoding::DefaultFuchsiaResourceDialect,
12869 >,
12870 offset: usize,
12871 depth: fidl::encoding::Depth,
12872 ) -> fidl::Result<()> {
12873 encoder.debug_check_bounds::<BufferCollectionInfo>(offset);
12874 // Zero out padding regions. There's no need to apply masks
12875 // because the unmasked parts will be overwritten by fields.
12876 unsafe {
12877 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
12878 (ptr as *mut u64).write_unaligned(0);
12879 }
12880 // Write the fields.
12881 self.0.encode(encoder, offset + 0, depth)?;
12882 self.1.encode(encoder, offset + 8, depth)?;
12883 self.2.encode(encoder, offset + 88, depth)?;
12884 self.3.encode(encoder, offset + 344, depth)?;
12885 Ok(())
12886 }
12887 }
12888
12889 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
12890 for BufferCollectionInfo
12891 {
12892 #[inline(always)]
12893 fn new_empty() -> Self {
12894 Self {
12895 buffer_count: fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect),
12896 format: fidl::new_empty!(
12897 BufferFormat,
12898 fidl::encoding::DefaultFuchsiaResourceDialect
12899 ),
12900 vmos: fidl::new_empty!(
12901 fidl::encoding::Array<
12902 fidl::encoding::Optional<
12903 fidl::encoding::HandleType<
12904 fidl::Vmo,
12905 { fidl::ObjectType::VMO.into_raw() },
12906 2147483648,
12907 >,
12908 >,
12909 64,
12910 >,
12911 fidl::encoding::DefaultFuchsiaResourceDialect
12912 ),
12913 vmo_size: fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect),
12914 }
12915 }
12916
12917 #[inline]
12918 unsafe fn decode(
12919 &mut self,
12920 decoder: &mut fidl::encoding::Decoder<
12921 '_,
12922 fidl::encoding::DefaultFuchsiaResourceDialect,
12923 >,
12924 offset: usize,
12925 _depth: fidl::encoding::Depth,
12926 ) -> fidl::Result<()> {
12927 decoder.debug_check_bounds::<Self>(offset);
12928 // Verify that padding bytes are zero.
12929 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
12930 let padval = unsafe { (ptr as *const u64).read_unaligned() };
12931 let mask = 0xffffffff00000000u64;
12932 let maskedval = padval & mask;
12933 if maskedval != 0 {
12934 return Err(fidl::Error::NonZeroPadding {
12935 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
12936 });
12937 }
12938 fidl::decode!(
12939 u32,
12940 fidl::encoding::DefaultFuchsiaResourceDialect,
12941 &mut self.buffer_count,
12942 decoder,
12943 offset + 0,
12944 _depth
12945 )?;
12946 fidl::decode!(
12947 BufferFormat,
12948 fidl::encoding::DefaultFuchsiaResourceDialect,
12949 &mut self.format,
12950 decoder,
12951 offset + 8,
12952 _depth
12953 )?;
12954 fidl::decode!(
12955 fidl::encoding::Array<
12956 fidl::encoding::Optional<
12957 fidl::encoding::HandleType<
12958 fidl::Vmo,
12959 { fidl::ObjectType::VMO.into_raw() },
12960 2147483648,
12961 >,
12962 >,
12963 64,
12964 >,
12965 fidl::encoding::DefaultFuchsiaResourceDialect,
12966 &mut self.vmos,
12967 decoder,
12968 offset + 88,
12969 _depth
12970 )?;
12971 fidl::decode!(
12972 u64,
12973 fidl::encoding::DefaultFuchsiaResourceDialect,
12974 &mut self.vmo_size,
12975 decoder,
12976 offset + 344,
12977 _depth
12978 )?;
12979 Ok(())
12980 }
12981 }
12982
12983 impl fidl::encoding::ResourceTypeMarker for BufferCollectionInfo2 {
12984 type Borrowed<'a> = &'a mut Self;
12985 fn take_or_borrow<'a>(
12986 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
12987 ) -> Self::Borrowed<'a> {
12988 value
12989 }
12990 }
12991
12992 unsafe impl fidl::encoding::TypeMarker for BufferCollectionInfo2 {
12993 type Owned = Self;
12994
12995 #[inline(always)]
12996 fn inline_align(_context: fidl::encoding::Context) -> usize {
12997 8
12998 }
12999
13000 #[inline(always)]
13001 fn inline_size(_context: fidl::encoding::Context) -> usize {
13002 1296
13003 }
13004 }
13005
13006 unsafe impl
13007 fidl::encoding::Encode<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>
13008 for &mut BufferCollectionInfo2
13009 {
13010 #[inline]
13011 unsafe fn encode(
13012 self,
13013 encoder: &mut fidl::encoding::Encoder<
13014 '_,
13015 fidl::encoding::DefaultFuchsiaResourceDialect,
13016 >,
13017 offset: usize,
13018 _depth: fidl::encoding::Depth,
13019 ) -> fidl::Result<()> {
13020 encoder.debug_check_bounds::<BufferCollectionInfo2>(offset);
13021 // Delegate to tuple encoding.
13022 fidl::encoding::Encode::<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
13023 (
13024 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.buffer_count),
13025 <SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow(&self.settings),
13026 <fidl::encoding::Array<VmoBuffer, 64> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffers),
13027 ),
13028 encoder, offset, _depth
13029 )
13030 }
13031 }
13032 unsafe impl<
13033 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13034 T1: fidl::encoding::Encode<SingleBufferSettings, fidl::encoding::DefaultFuchsiaResourceDialect>,
13035 T2: fidl::encoding::Encode<
13036 fidl::encoding::Array<VmoBuffer, 64>,
13037 fidl::encoding::DefaultFuchsiaResourceDialect,
13038 >,
13039 >
13040 fidl::encoding::Encode<BufferCollectionInfo2, fidl::encoding::DefaultFuchsiaResourceDialect>
13041 for (T0, T1, T2)
13042 {
13043 #[inline]
13044 unsafe fn encode(
13045 self,
13046 encoder: &mut fidl::encoding::Encoder<
13047 '_,
13048 fidl::encoding::DefaultFuchsiaResourceDialect,
13049 >,
13050 offset: usize,
13051 depth: fidl::encoding::Depth,
13052 ) -> fidl::Result<()> {
13053 encoder.debug_check_bounds::<BufferCollectionInfo2>(offset);
13054 // Zero out padding regions. There's no need to apply masks
13055 // because the unmasked parts will be overwritten by fields.
13056 unsafe {
13057 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
13058 (ptr as *mut u64).write_unaligned(0);
13059 }
13060 // Write the fields.
13061 self.0.encode(encoder, offset + 0, depth)?;
13062 self.1.encode(encoder, offset + 8, depth)?;
13063 self.2.encode(encoder, offset + 272, depth)?;
13064 Ok(())
13065 }
13066 }
13067
13068 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13069 for BufferCollectionInfo2
13070 {
13071 #[inline(always)]
13072 fn new_empty() -> Self {
13073 Self {
13074 buffer_count: fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect),
13075 settings: fidl::new_empty!(
13076 SingleBufferSettings,
13077 fidl::encoding::DefaultFuchsiaResourceDialect
13078 ),
13079 buffers: fidl::new_empty!(fidl::encoding::Array<VmoBuffer, 64>, fidl::encoding::DefaultFuchsiaResourceDialect),
13080 }
13081 }
13082
13083 #[inline]
13084 unsafe fn decode(
13085 &mut self,
13086 decoder: &mut fidl::encoding::Decoder<
13087 '_,
13088 fidl::encoding::DefaultFuchsiaResourceDialect,
13089 >,
13090 offset: usize,
13091 _depth: fidl::encoding::Depth,
13092 ) -> fidl::Result<()> {
13093 decoder.debug_check_bounds::<Self>(offset);
13094 // Verify that padding bytes are zero.
13095 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
13096 let padval = unsafe { (ptr as *const u64).read_unaligned() };
13097 let mask = 0xffffffff00000000u64;
13098 let maskedval = padval & mask;
13099 if maskedval != 0 {
13100 return Err(fidl::Error::NonZeroPadding {
13101 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
13102 });
13103 }
13104 fidl::decode!(
13105 u32,
13106 fidl::encoding::DefaultFuchsiaResourceDialect,
13107 &mut self.buffer_count,
13108 decoder,
13109 offset + 0,
13110 _depth
13111 )?;
13112 fidl::decode!(
13113 SingleBufferSettings,
13114 fidl::encoding::DefaultFuchsiaResourceDialect,
13115 &mut self.settings,
13116 decoder,
13117 offset + 8,
13118 _depth
13119 )?;
13120 fidl::decode!(fidl::encoding::Array<VmoBuffer, 64>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.buffers, decoder, offset + 272, _depth)?;
13121 Ok(())
13122 }
13123 }
13124
13125 impl fidl::encoding::ResourceTypeMarker
13126 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13127 {
13128 type Borrowed<'a> = &'a mut Self;
13129 fn take_or_borrow<'a>(
13130 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13131 ) -> Self::Borrowed<'a> {
13132 value
13133 }
13134 }
13135
13136 unsafe impl fidl::encoding::TypeMarker
13137 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13138 {
13139 type Owned = Self;
13140
13141 #[inline(always)]
13142 fn inline_align(_context: fidl::encoding::Context) -> usize {
13143 4
13144 }
13145
13146 #[inline(always)]
13147 fn inline_size(_context: fidl::encoding::Context) -> usize {
13148 4
13149 }
13150 }
13151
13152 unsafe impl
13153 fidl::encoding::Encode<
13154 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13155 fidl::encoding::DefaultFuchsiaResourceDialect,
13156 > for &mut BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13157 {
13158 #[inline]
13159 unsafe fn encode(
13160 self,
13161 encoder: &mut fidl::encoding::Encoder<
13162 '_,
13163 fidl::encoding::DefaultFuchsiaResourceDialect,
13164 >,
13165 offset: usize,
13166 _depth: fidl::encoding::Depth,
13167 ) -> fidl::Result<()> {
13168 encoder
13169 .debug_check_bounds::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
13170 offset,
13171 );
13172 // Delegate to tuple encoding.
13173 fidl::encoding::Encode::<
13174 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13175 fidl::encoding::DefaultFuchsiaResourceDialect,
13176 >::encode(
13177 (<fidl::encoding::Endpoint<
13178 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13179 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13180 &mut self.group_request
13181 ),),
13182 encoder,
13183 offset,
13184 _depth,
13185 )
13186 }
13187 }
13188 unsafe impl<
13189 T0: fidl::encoding::Encode<
13190 fidl::encoding::Endpoint<
13191 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13192 >,
13193 fidl::encoding::DefaultFuchsiaResourceDialect,
13194 >,
13195 >
13196 fidl::encoding::Encode<
13197 BufferCollectionTokenCreateBufferCollectionTokenGroupRequest,
13198 fidl::encoding::DefaultFuchsiaResourceDialect,
13199 > for (T0,)
13200 {
13201 #[inline]
13202 unsafe fn encode(
13203 self,
13204 encoder: &mut fidl::encoding::Encoder<
13205 '_,
13206 fidl::encoding::DefaultFuchsiaResourceDialect,
13207 >,
13208 offset: usize,
13209 depth: fidl::encoding::Depth,
13210 ) -> fidl::Result<()> {
13211 encoder
13212 .debug_check_bounds::<BufferCollectionTokenCreateBufferCollectionTokenGroupRequest>(
13213 offset,
13214 );
13215 // Zero out padding regions. There's no need to apply masks
13216 // because the unmasked parts will be overwritten by fields.
13217 // Write the fields.
13218 self.0.encode(encoder, offset + 0, depth)?;
13219 Ok(())
13220 }
13221 }
13222
13223 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13224 for BufferCollectionTokenCreateBufferCollectionTokenGroupRequest
13225 {
13226 #[inline(always)]
13227 fn new_empty() -> Self {
13228 Self {
13229 group_request: fidl::new_empty!(
13230 fidl::encoding::Endpoint<
13231 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13232 >,
13233 fidl::encoding::DefaultFuchsiaResourceDialect
13234 ),
13235 }
13236 }
13237
13238 #[inline]
13239 unsafe fn decode(
13240 &mut self,
13241 decoder: &mut fidl::encoding::Decoder<
13242 '_,
13243 fidl::encoding::DefaultFuchsiaResourceDialect,
13244 >,
13245 offset: usize,
13246 _depth: fidl::encoding::Depth,
13247 ) -> fidl::Result<()> {
13248 decoder.debug_check_bounds::<Self>(offset);
13249 // Verify that padding bytes are zero.
13250 fidl::decode!(
13251 fidl::encoding::Endpoint<
13252 fidl::endpoints::ServerEnd<BufferCollectionTokenGroupMarker>,
13253 >,
13254 fidl::encoding::DefaultFuchsiaResourceDialect,
13255 &mut self.group_request,
13256 decoder,
13257 offset + 0,
13258 _depth
13259 )?;
13260 Ok(())
13261 }
13262 }
13263
13264 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateRequest {
13265 type Borrowed<'a> = &'a mut Self;
13266 fn take_or_borrow<'a>(
13267 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13268 ) -> Self::Borrowed<'a> {
13269 value
13270 }
13271 }
13272
13273 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateRequest {
13274 type Owned = Self;
13275
13276 #[inline(always)]
13277 fn inline_align(_context: fidl::encoding::Context) -> usize {
13278 4
13279 }
13280
13281 #[inline(always)]
13282 fn inline_size(_context: fidl::encoding::Context) -> usize {
13283 8
13284 }
13285 }
13286
13287 unsafe impl
13288 fidl::encoding::Encode<
13289 BufferCollectionTokenDuplicateRequest,
13290 fidl::encoding::DefaultFuchsiaResourceDialect,
13291 > for &mut BufferCollectionTokenDuplicateRequest
13292 {
13293 #[inline]
13294 unsafe fn encode(
13295 self,
13296 encoder: &mut fidl::encoding::Encoder<
13297 '_,
13298 fidl::encoding::DefaultFuchsiaResourceDialect,
13299 >,
13300 offset: usize,
13301 _depth: fidl::encoding::Depth,
13302 ) -> fidl::Result<()> {
13303 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateRequest>(offset);
13304 // Delegate to tuple encoding.
13305 fidl::encoding::Encode::<
13306 BufferCollectionTokenDuplicateRequest,
13307 fidl::encoding::DefaultFuchsiaResourceDialect,
13308 >::encode(
13309 (
13310 <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.rights_attenuation_mask),
13311 <fidl::encoding::Endpoint<
13312 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
13313 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13314 &mut self.token_request,
13315 ),
13316 ),
13317 encoder,
13318 offset,
13319 _depth,
13320 )
13321 }
13322 }
13323 unsafe impl<
13324 T0: fidl::encoding::Encode<u32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13325 T1: fidl::encoding::Encode<
13326 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
13327 fidl::encoding::DefaultFuchsiaResourceDialect,
13328 >,
13329 >
13330 fidl::encoding::Encode<
13331 BufferCollectionTokenDuplicateRequest,
13332 fidl::encoding::DefaultFuchsiaResourceDialect,
13333 > for (T0, T1)
13334 {
13335 #[inline]
13336 unsafe fn encode(
13337 self,
13338 encoder: &mut fidl::encoding::Encoder<
13339 '_,
13340 fidl::encoding::DefaultFuchsiaResourceDialect,
13341 >,
13342 offset: usize,
13343 depth: fidl::encoding::Depth,
13344 ) -> fidl::Result<()> {
13345 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateRequest>(offset);
13346 // Zero out padding regions. There's no need to apply masks
13347 // because the unmasked parts will be overwritten by fields.
13348 // Write the fields.
13349 self.0.encode(encoder, offset + 0, depth)?;
13350 self.1.encode(encoder, offset + 4, depth)?;
13351 Ok(())
13352 }
13353 }
13354
13355 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13356 for BufferCollectionTokenDuplicateRequest
13357 {
13358 #[inline(always)]
13359 fn new_empty() -> Self {
13360 Self {
13361 rights_attenuation_mask: fidl::new_empty!(
13362 u32,
13363 fidl::encoding::DefaultFuchsiaResourceDialect
13364 ),
13365 token_request: fidl::new_empty!(
13366 fidl::encoding::Endpoint<
13367 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
13368 >,
13369 fidl::encoding::DefaultFuchsiaResourceDialect
13370 ),
13371 }
13372 }
13373
13374 #[inline]
13375 unsafe fn decode(
13376 &mut self,
13377 decoder: &mut fidl::encoding::Decoder<
13378 '_,
13379 fidl::encoding::DefaultFuchsiaResourceDialect,
13380 >,
13381 offset: usize,
13382 _depth: fidl::encoding::Depth,
13383 ) -> fidl::Result<()> {
13384 decoder.debug_check_bounds::<Self>(offset);
13385 // Verify that padding bytes are zero.
13386 fidl::decode!(
13387 u32,
13388 fidl::encoding::DefaultFuchsiaResourceDialect,
13389 &mut self.rights_attenuation_mask,
13390 decoder,
13391 offset + 0,
13392 _depth
13393 )?;
13394 fidl::decode!(
13395 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
13396 fidl::encoding::DefaultFuchsiaResourceDialect,
13397 &mut self.token_request,
13398 decoder,
13399 offset + 4,
13400 _depth
13401 )?;
13402 Ok(())
13403 }
13404 }
13405
13406 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenDuplicateSyncResponse {
13407 type Borrowed<'a> = &'a mut Self;
13408 fn take_or_borrow<'a>(
13409 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13410 ) -> Self::Borrowed<'a> {
13411 value
13412 }
13413 }
13414
13415 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenDuplicateSyncResponse {
13416 type Owned = Self;
13417
13418 #[inline(always)]
13419 fn inline_align(_context: fidl::encoding::Context) -> usize {
13420 8
13421 }
13422
13423 #[inline(always)]
13424 fn inline_size(_context: fidl::encoding::Context) -> usize {
13425 16
13426 }
13427 }
13428
13429 unsafe impl
13430 fidl::encoding::Encode<
13431 BufferCollectionTokenDuplicateSyncResponse,
13432 fidl::encoding::DefaultFuchsiaResourceDialect,
13433 > for &mut BufferCollectionTokenDuplicateSyncResponse
13434 {
13435 #[inline]
13436 unsafe fn encode(
13437 self,
13438 encoder: &mut fidl::encoding::Encoder<
13439 '_,
13440 fidl::encoding::DefaultFuchsiaResourceDialect,
13441 >,
13442 offset: usize,
13443 _depth: fidl::encoding::Depth,
13444 ) -> fidl::Result<()> {
13445 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateSyncResponse>(offset);
13446 // Delegate to tuple encoding.
13447 fidl::encoding::Encode::<
13448 BufferCollectionTokenDuplicateSyncResponse,
13449 fidl::encoding::DefaultFuchsiaResourceDialect,
13450 >::encode(
13451 (<fidl::encoding::Vector<
13452 fidl::encoding::Endpoint<
13453 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13454 >,
13455 64,
13456 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13457 &mut self.tokens
13458 ),),
13459 encoder,
13460 offset,
13461 _depth,
13462 )
13463 }
13464 }
13465 unsafe impl<
13466 T0: fidl::encoding::Encode<
13467 fidl::encoding::Vector<
13468 fidl::encoding::Endpoint<
13469 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13470 >,
13471 64,
13472 >,
13473 fidl::encoding::DefaultFuchsiaResourceDialect,
13474 >,
13475 >
13476 fidl::encoding::Encode<
13477 BufferCollectionTokenDuplicateSyncResponse,
13478 fidl::encoding::DefaultFuchsiaResourceDialect,
13479 > for (T0,)
13480 {
13481 #[inline]
13482 unsafe fn encode(
13483 self,
13484 encoder: &mut fidl::encoding::Encoder<
13485 '_,
13486 fidl::encoding::DefaultFuchsiaResourceDialect,
13487 >,
13488 offset: usize,
13489 depth: fidl::encoding::Depth,
13490 ) -> fidl::Result<()> {
13491 encoder.debug_check_bounds::<BufferCollectionTokenDuplicateSyncResponse>(offset);
13492 // Zero out padding regions. There's no need to apply masks
13493 // because the unmasked parts will be overwritten by fields.
13494 // Write the fields.
13495 self.0.encode(encoder, offset + 0, depth)?;
13496 Ok(())
13497 }
13498 }
13499
13500 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13501 for BufferCollectionTokenDuplicateSyncResponse
13502 {
13503 #[inline(always)]
13504 fn new_empty() -> Self {
13505 Self {
13506 tokens: fidl::new_empty!(
13507 fidl::encoding::Vector<
13508 fidl::encoding::Endpoint<
13509 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13510 >,
13511 64,
13512 >,
13513 fidl::encoding::DefaultFuchsiaResourceDialect
13514 ),
13515 }
13516 }
13517
13518 #[inline]
13519 unsafe fn decode(
13520 &mut self,
13521 decoder: &mut fidl::encoding::Decoder<
13522 '_,
13523 fidl::encoding::DefaultFuchsiaResourceDialect,
13524 >,
13525 offset: usize,
13526 _depth: fidl::encoding::Depth,
13527 ) -> fidl::Result<()> {
13528 decoder.debug_check_bounds::<Self>(offset);
13529 // Verify that padding bytes are zero.
13530 fidl::decode!(
13531 fidl::encoding::Vector<
13532 fidl::encoding::Endpoint<
13533 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13534 >,
13535 64,
13536 >,
13537 fidl::encoding::DefaultFuchsiaResourceDialect,
13538 &mut self.tokens,
13539 decoder,
13540 offset + 0,
13541 _depth
13542 )?;
13543 Ok(())
13544 }
13545 }
13546
13547 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
13548 type Borrowed<'a> = &'a mut Self;
13549 fn take_or_borrow<'a>(
13550 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13551 ) -> Self::Borrowed<'a> {
13552 value
13553 }
13554 }
13555
13556 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildrenSyncResponse {
13557 type Owned = Self;
13558
13559 #[inline(always)]
13560 fn inline_align(_context: fidl::encoding::Context) -> usize {
13561 8
13562 }
13563
13564 #[inline(always)]
13565 fn inline_size(_context: fidl::encoding::Context) -> usize {
13566 16
13567 }
13568 }
13569
13570 unsafe impl
13571 fidl::encoding::Encode<
13572 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13573 fidl::encoding::DefaultFuchsiaResourceDialect,
13574 > for &mut BufferCollectionTokenGroupCreateChildrenSyncResponse
13575 {
13576 #[inline]
13577 unsafe fn encode(
13578 self,
13579 encoder: &mut fidl::encoding::Encoder<
13580 '_,
13581 fidl::encoding::DefaultFuchsiaResourceDialect,
13582 >,
13583 offset: usize,
13584 _depth: fidl::encoding::Depth,
13585 ) -> fidl::Result<()> {
13586 encoder
13587 .debug_check_bounds::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(offset);
13588 // Delegate to tuple encoding.
13589 fidl::encoding::Encode::<
13590 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13591 fidl::encoding::DefaultFuchsiaResourceDialect,
13592 >::encode(
13593 (<fidl::encoding::Vector<
13594 fidl::encoding::Endpoint<
13595 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13596 >,
13597 64,
13598 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13599 &mut self.tokens
13600 ),),
13601 encoder,
13602 offset,
13603 _depth,
13604 )
13605 }
13606 }
13607 unsafe impl<
13608 T0: fidl::encoding::Encode<
13609 fidl::encoding::Vector<
13610 fidl::encoding::Endpoint<
13611 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13612 >,
13613 64,
13614 >,
13615 fidl::encoding::DefaultFuchsiaResourceDialect,
13616 >,
13617 >
13618 fidl::encoding::Encode<
13619 BufferCollectionTokenGroupCreateChildrenSyncResponse,
13620 fidl::encoding::DefaultFuchsiaResourceDialect,
13621 > for (T0,)
13622 {
13623 #[inline]
13624 unsafe fn encode(
13625 self,
13626 encoder: &mut fidl::encoding::Encoder<
13627 '_,
13628 fidl::encoding::DefaultFuchsiaResourceDialect,
13629 >,
13630 offset: usize,
13631 depth: fidl::encoding::Depth,
13632 ) -> fidl::Result<()> {
13633 encoder
13634 .debug_check_bounds::<BufferCollectionTokenGroupCreateChildrenSyncResponse>(offset);
13635 // Zero out padding regions. There's no need to apply masks
13636 // because the unmasked parts will be overwritten by fields.
13637 // Write the fields.
13638 self.0.encode(encoder, offset + 0, depth)?;
13639 Ok(())
13640 }
13641 }
13642
13643 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13644 for BufferCollectionTokenGroupCreateChildrenSyncResponse
13645 {
13646 #[inline(always)]
13647 fn new_empty() -> Self {
13648 Self {
13649 tokens: fidl::new_empty!(
13650 fidl::encoding::Vector<
13651 fidl::encoding::Endpoint<
13652 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13653 >,
13654 64,
13655 >,
13656 fidl::encoding::DefaultFuchsiaResourceDialect
13657 ),
13658 }
13659 }
13660
13661 #[inline]
13662 unsafe fn decode(
13663 &mut self,
13664 decoder: &mut fidl::encoding::Decoder<
13665 '_,
13666 fidl::encoding::DefaultFuchsiaResourceDialect,
13667 >,
13668 offset: usize,
13669 _depth: fidl::encoding::Depth,
13670 ) -> fidl::Result<()> {
13671 decoder.debug_check_bounds::<Self>(offset);
13672 // Verify that padding bytes are zero.
13673 fidl::decode!(
13674 fidl::encoding::Vector<
13675 fidl::encoding::Endpoint<
13676 fidl::endpoints::ClientEnd<BufferCollectionTokenMarker>,
13677 >,
13678 64,
13679 >,
13680 fidl::encoding::DefaultFuchsiaResourceDialect,
13681 &mut self.tokens,
13682 decoder,
13683 offset + 0,
13684 _depth
13685 )?;
13686 Ok(())
13687 }
13688 }
13689
13690 impl fidl::encoding::ResourceTypeMarker for BufferCollectionWaitForBuffersAllocatedResponse {
13691 type Borrowed<'a> = &'a mut Self;
13692 fn take_or_borrow<'a>(
13693 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13694 ) -> Self::Borrowed<'a> {
13695 value
13696 }
13697 }
13698
13699 unsafe impl fidl::encoding::TypeMarker for BufferCollectionWaitForBuffersAllocatedResponse {
13700 type Owned = Self;
13701
13702 #[inline(always)]
13703 fn inline_align(_context: fidl::encoding::Context) -> usize {
13704 8
13705 }
13706
13707 #[inline(always)]
13708 fn inline_size(_context: fidl::encoding::Context) -> usize {
13709 1304
13710 }
13711 }
13712
13713 unsafe impl
13714 fidl::encoding::Encode<
13715 BufferCollectionWaitForBuffersAllocatedResponse,
13716 fidl::encoding::DefaultFuchsiaResourceDialect,
13717 > for &mut BufferCollectionWaitForBuffersAllocatedResponse
13718 {
13719 #[inline]
13720 unsafe fn encode(
13721 self,
13722 encoder: &mut fidl::encoding::Encoder<
13723 '_,
13724 fidl::encoding::DefaultFuchsiaResourceDialect,
13725 >,
13726 offset: usize,
13727 _depth: fidl::encoding::Depth,
13728 ) -> fidl::Result<()> {
13729 encoder.debug_check_bounds::<BufferCollectionWaitForBuffersAllocatedResponse>(offset);
13730 // Delegate to tuple encoding.
13731 fidl::encoding::Encode::<
13732 BufferCollectionWaitForBuffersAllocatedResponse,
13733 fidl::encoding::DefaultFuchsiaResourceDialect,
13734 >::encode(
13735 (
13736 <i32 as fidl::encoding::ValueTypeMarker>::borrow(&self.status),
13737 <BufferCollectionInfo2 as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13738 &mut self.buffer_collection_info,
13739 ),
13740 ),
13741 encoder,
13742 offset,
13743 _depth,
13744 )
13745 }
13746 }
13747 unsafe impl<
13748 T0: fidl::encoding::Encode<i32, fidl::encoding::DefaultFuchsiaResourceDialect>,
13749 T1: fidl::encoding::Encode<
13750 BufferCollectionInfo2,
13751 fidl::encoding::DefaultFuchsiaResourceDialect,
13752 >,
13753 >
13754 fidl::encoding::Encode<
13755 BufferCollectionWaitForBuffersAllocatedResponse,
13756 fidl::encoding::DefaultFuchsiaResourceDialect,
13757 > for (T0, T1)
13758 {
13759 #[inline]
13760 unsafe fn encode(
13761 self,
13762 encoder: &mut fidl::encoding::Encoder<
13763 '_,
13764 fidl::encoding::DefaultFuchsiaResourceDialect,
13765 >,
13766 offset: usize,
13767 depth: fidl::encoding::Depth,
13768 ) -> fidl::Result<()> {
13769 encoder.debug_check_bounds::<BufferCollectionWaitForBuffersAllocatedResponse>(offset);
13770 // Zero out padding regions. There's no need to apply masks
13771 // because the unmasked parts will be overwritten by fields.
13772 unsafe {
13773 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
13774 (ptr as *mut u64).write_unaligned(0);
13775 }
13776 // Write the fields.
13777 self.0.encode(encoder, offset + 0, depth)?;
13778 self.1.encode(encoder, offset + 8, depth)?;
13779 Ok(())
13780 }
13781 }
13782
13783 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13784 for BufferCollectionWaitForBuffersAllocatedResponse
13785 {
13786 #[inline(always)]
13787 fn new_empty() -> Self {
13788 Self {
13789 status: fidl::new_empty!(i32, fidl::encoding::DefaultFuchsiaResourceDialect),
13790 buffer_collection_info: fidl::new_empty!(
13791 BufferCollectionInfo2,
13792 fidl::encoding::DefaultFuchsiaResourceDialect
13793 ),
13794 }
13795 }
13796
13797 #[inline]
13798 unsafe fn decode(
13799 &mut self,
13800 decoder: &mut fidl::encoding::Decoder<
13801 '_,
13802 fidl::encoding::DefaultFuchsiaResourceDialect,
13803 >,
13804 offset: usize,
13805 _depth: fidl::encoding::Depth,
13806 ) -> fidl::Result<()> {
13807 decoder.debug_check_bounds::<Self>(offset);
13808 // Verify that padding bytes are zero.
13809 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
13810 let padval = unsafe { (ptr as *const u64).read_unaligned() };
13811 let mask = 0xffffffff00000000u64;
13812 let maskedval = padval & mask;
13813 if maskedval != 0 {
13814 return Err(fidl::Error::NonZeroPadding {
13815 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
13816 });
13817 }
13818 fidl::decode!(
13819 i32,
13820 fidl::encoding::DefaultFuchsiaResourceDialect,
13821 &mut self.status,
13822 decoder,
13823 offset + 0,
13824 _depth
13825 )?;
13826 fidl::decode!(
13827 BufferCollectionInfo2,
13828 fidl::encoding::DefaultFuchsiaResourceDialect,
13829 &mut self.buffer_collection_info,
13830 decoder,
13831 offset + 8,
13832 _depth
13833 )?;
13834 Ok(())
13835 }
13836 }
13837
13838 impl fidl::encoding::ResourceTypeMarker for NodeGetNodeRefResponse {
13839 type Borrowed<'a> = &'a mut Self;
13840 fn take_or_borrow<'a>(
13841 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13842 ) -> Self::Borrowed<'a> {
13843 value
13844 }
13845 }
13846
13847 unsafe impl fidl::encoding::TypeMarker for NodeGetNodeRefResponse {
13848 type Owned = Self;
13849
13850 #[inline(always)]
13851 fn inline_align(_context: fidl::encoding::Context) -> usize {
13852 4
13853 }
13854
13855 #[inline(always)]
13856 fn inline_size(_context: fidl::encoding::Context) -> usize {
13857 4
13858 }
13859 }
13860
13861 unsafe impl
13862 fidl::encoding::Encode<
13863 NodeGetNodeRefResponse,
13864 fidl::encoding::DefaultFuchsiaResourceDialect,
13865 > for &mut NodeGetNodeRefResponse
13866 {
13867 #[inline]
13868 unsafe fn encode(
13869 self,
13870 encoder: &mut fidl::encoding::Encoder<
13871 '_,
13872 fidl::encoding::DefaultFuchsiaResourceDialect,
13873 >,
13874 offset: usize,
13875 _depth: fidl::encoding::Depth,
13876 ) -> fidl::Result<()> {
13877 encoder.debug_check_bounds::<NodeGetNodeRefResponse>(offset);
13878 // Delegate to tuple encoding.
13879 fidl::encoding::Encode::<
13880 NodeGetNodeRefResponse,
13881 fidl::encoding::DefaultFuchsiaResourceDialect,
13882 >::encode(
13883 (<fidl::encoding::HandleType<
13884 fidl::Event,
13885 { fidl::ObjectType::EVENT.into_raw() },
13886 2147483648,
13887 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
13888 &mut self.node_ref
13889 ),),
13890 encoder,
13891 offset,
13892 _depth,
13893 )
13894 }
13895 }
13896 unsafe impl<
13897 T0: fidl::encoding::Encode<
13898 fidl::encoding::HandleType<
13899 fidl::Event,
13900 { fidl::ObjectType::EVENT.into_raw() },
13901 2147483648,
13902 >,
13903 fidl::encoding::DefaultFuchsiaResourceDialect,
13904 >,
13905 >
13906 fidl::encoding::Encode<
13907 NodeGetNodeRefResponse,
13908 fidl::encoding::DefaultFuchsiaResourceDialect,
13909 > for (T0,)
13910 {
13911 #[inline]
13912 unsafe fn encode(
13913 self,
13914 encoder: &mut fidl::encoding::Encoder<
13915 '_,
13916 fidl::encoding::DefaultFuchsiaResourceDialect,
13917 >,
13918 offset: usize,
13919 depth: fidl::encoding::Depth,
13920 ) -> fidl::Result<()> {
13921 encoder.debug_check_bounds::<NodeGetNodeRefResponse>(offset);
13922 // Zero out padding regions. There's no need to apply masks
13923 // because the unmasked parts will be overwritten by fields.
13924 // Write the fields.
13925 self.0.encode(encoder, offset + 0, depth)?;
13926 Ok(())
13927 }
13928 }
13929
13930 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
13931 for NodeGetNodeRefResponse
13932 {
13933 #[inline(always)]
13934 fn new_empty() -> Self {
13935 Self {
13936 node_ref: fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
13937 }
13938 }
13939
13940 #[inline]
13941 unsafe fn decode(
13942 &mut self,
13943 decoder: &mut fidl::encoding::Decoder<
13944 '_,
13945 fidl::encoding::DefaultFuchsiaResourceDialect,
13946 >,
13947 offset: usize,
13948 _depth: fidl::encoding::Depth,
13949 ) -> fidl::Result<()> {
13950 decoder.debug_check_bounds::<Self>(offset);
13951 // Verify that padding bytes are zero.
13952 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.node_ref, decoder, offset + 0, _depth)?;
13953 Ok(())
13954 }
13955 }
13956
13957 impl fidl::encoding::ResourceTypeMarker for NodeIsAlternateForRequest {
13958 type Borrowed<'a> = &'a mut Self;
13959 fn take_or_borrow<'a>(
13960 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
13961 ) -> Self::Borrowed<'a> {
13962 value
13963 }
13964 }
13965
13966 unsafe impl fidl::encoding::TypeMarker for NodeIsAlternateForRequest {
13967 type Owned = Self;
13968
13969 #[inline(always)]
13970 fn inline_align(_context: fidl::encoding::Context) -> usize {
13971 4
13972 }
13973
13974 #[inline(always)]
13975 fn inline_size(_context: fidl::encoding::Context) -> usize {
13976 4
13977 }
13978 }
13979
13980 unsafe impl
13981 fidl::encoding::Encode<
13982 NodeIsAlternateForRequest,
13983 fidl::encoding::DefaultFuchsiaResourceDialect,
13984 > for &mut NodeIsAlternateForRequest
13985 {
13986 #[inline]
13987 unsafe fn encode(
13988 self,
13989 encoder: &mut fidl::encoding::Encoder<
13990 '_,
13991 fidl::encoding::DefaultFuchsiaResourceDialect,
13992 >,
13993 offset: usize,
13994 _depth: fidl::encoding::Depth,
13995 ) -> fidl::Result<()> {
13996 encoder.debug_check_bounds::<NodeIsAlternateForRequest>(offset);
13997 // Delegate to tuple encoding.
13998 fidl::encoding::Encode::<
13999 NodeIsAlternateForRequest,
14000 fidl::encoding::DefaultFuchsiaResourceDialect,
14001 >::encode(
14002 (<fidl::encoding::HandleType<
14003 fidl::Event,
14004 { fidl::ObjectType::EVENT.into_raw() },
14005 2147483648,
14006 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
14007 &mut self.node_ref
14008 ),),
14009 encoder,
14010 offset,
14011 _depth,
14012 )
14013 }
14014 }
14015 unsafe impl<
14016 T0: fidl::encoding::Encode<
14017 fidl::encoding::HandleType<
14018 fidl::Event,
14019 { fidl::ObjectType::EVENT.into_raw() },
14020 2147483648,
14021 >,
14022 fidl::encoding::DefaultFuchsiaResourceDialect,
14023 >,
14024 >
14025 fidl::encoding::Encode<
14026 NodeIsAlternateForRequest,
14027 fidl::encoding::DefaultFuchsiaResourceDialect,
14028 > for (T0,)
14029 {
14030 #[inline]
14031 unsafe fn encode(
14032 self,
14033 encoder: &mut fidl::encoding::Encoder<
14034 '_,
14035 fidl::encoding::DefaultFuchsiaResourceDialect,
14036 >,
14037 offset: usize,
14038 depth: fidl::encoding::Depth,
14039 ) -> fidl::Result<()> {
14040 encoder.debug_check_bounds::<NodeIsAlternateForRequest>(offset);
14041 // Zero out padding regions. There's no need to apply masks
14042 // because the unmasked parts will be overwritten by fields.
14043 // Write the fields.
14044 self.0.encode(encoder, offset + 0, depth)?;
14045 Ok(())
14046 }
14047 }
14048
14049 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14050 for NodeIsAlternateForRequest
14051 {
14052 #[inline(always)]
14053 fn new_empty() -> Self {
14054 Self {
14055 node_ref: fidl::new_empty!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
14056 }
14057 }
14058
14059 #[inline]
14060 unsafe fn decode(
14061 &mut self,
14062 decoder: &mut fidl::encoding::Decoder<
14063 '_,
14064 fidl::encoding::DefaultFuchsiaResourceDialect,
14065 >,
14066 offset: usize,
14067 _depth: fidl::encoding::Depth,
14068 ) -> fidl::Result<()> {
14069 decoder.debug_check_bounds::<Self>(offset);
14070 // Verify that padding bytes are zero.
14071 fidl::decode!(fidl::encoding::HandleType<fidl::Event, { fidl::ObjectType::EVENT.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.node_ref, decoder, offset + 0, _depth)?;
14072 Ok(())
14073 }
14074 }
14075
14076 impl fidl::encoding::ResourceTypeMarker for SingleBufferInfo {
14077 type Borrowed<'a> = &'a mut Self;
14078 fn take_or_borrow<'a>(
14079 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14080 ) -> Self::Borrowed<'a> {
14081 value
14082 }
14083 }
14084
14085 unsafe impl fidl::encoding::TypeMarker for SingleBufferInfo {
14086 type Owned = Self;
14087
14088 #[inline(always)]
14089 fn inline_align(_context: fidl::encoding::Context) -> usize {
14090 8
14091 }
14092
14093 #[inline(always)]
14094 fn inline_size(_context: fidl::encoding::Context) -> usize {
14095 280
14096 }
14097 }
14098
14099 unsafe impl
14100 fidl::encoding::Encode<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
14101 for &mut SingleBufferInfo
14102 {
14103 #[inline]
14104 unsafe fn encode(
14105 self,
14106 encoder: &mut fidl::encoding::Encoder<
14107 '_,
14108 fidl::encoding::DefaultFuchsiaResourceDialect,
14109 >,
14110 offset: usize,
14111 _depth: fidl::encoding::Depth,
14112 ) -> fidl::Result<()> {
14113 encoder.debug_check_bounds::<SingleBufferInfo>(offset);
14114 // Delegate to tuple encoding.
14115 fidl::encoding::Encode::<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
14116 (
14117 <SingleBufferSettings as fidl::encoding::ValueTypeMarker>::borrow(&self.settings),
14118 <VmoBuffer as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.buffer),
14119 ),
14120 encoder, offset, _depth
14121 )
14122 }
14123 }
14124 unsafe impl<
14125 T0: fidl::encoding::Encode<SingleBufferSettings, fidl::encoding::DefaultFuchsiaResourceDialect>,
14126 T1: fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>,
14127 > fidl::encoding::Encode<SingleBufferInfo, fidl::encoding::DefaultFuchsiaResourceDialect>
14128 for (T0, T1)
14129 {
14130 #[inline]
14131 unsafe fn encode(
14132 self,
14133 encoder: &mut fidl::encoding::Encoder<
14134 '_,
14135 fidl::encoding::DefaultFuchsiaResourceDialect,
14136 >,
14137 offset: usize,
14138 depth: fidl::encoding::Depth,
14139 ) -> fidl::Result<()> {
14140 encoder.debug_check_bounds::<SingleBufferInfo>(offset);
14141 // Zero out padding regions. There's no need to apply masks
14142 // because the unmasked parts will be overwritten by fields.
14143 // Write the fields.
14144 self.0.encode(encoder, offset + 0, depth)?;
14145 self.1.encode(encoder, offset + 264, depth)?;
14146 Ok(())
14147 }
14148 }
14149
14150 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14151 for SingleBufferInfo
14152 {
14153 #[inline(always)]
14154 fn new_empty() -> Self {
14155 Self {
14156 settings: fidl::new_empty!(
14157 SingleBufferSettings,
14158 fidl::encoding::DefaultFuchsiaResourceDialect
14159 ),
14160 buffer: fidl::new_empty!(VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect),
14161 }
14162 }
14163
14164 #[inline]
14165 unsafe fn decode(
14166 &mut self,
14167 decoder: &mut fidl::encoding::Decoder<
14168 '_,
14169 fidl::encoding::DefaultFuchsiaResourceDialect,
14170 >,
14171 offset: usize,
14172 _depth: fidl::encoding::Depth,
14173 ) -> fidl::Result<()> {
14174 decoder.debug_check_bounds::<Self>(offset);
14175 // Verify that padding bytes are zero.
14176 fidl::decode!(
14177 SingleBufferSettings,
14178 fidl::encoding::DefaultFuchsiaResourceDialect,
14179 &mut self.settings,
14180 decoder,
14181 offset + 0,
14182 _depth
14183 )?;
14184 fidl::decode!(
14185 VmoBuffer,
14186 fidl::encoding::DefaultFuchsiaResourceDialect,
14187 &mut self.buffer,
14188 decoder,
14189 offset + 264,
14190 _depth
14191 )?;
14192 Ok(())
14193 }
14194 }
14195
14196 impl fidl::encoding::ResourceTypeMarker for VmoBuffer {
14197 type Borrowed<'a> = &'a mut Self;
14198 fn take_or_borrow<'a>(
14199 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14200 ) -> Self::Borrowed<'a> {
14201 value
14202 }
14203 }
14204
14205 unsafe impl fidl::encoding::TypeMarker for VmoBuffer {
14206 type Owned = Self;
14207
14208 #[inline(always)]
14209 fn inline_align(_context: fidl::encoding::Context) -> usize {
14210 8
14211 }
14212
14213 #[inline(always)]
14214 fn inline_size(_context: fidl::encoding::Context) -> usize {
14215 16
14216 }
14217 }
14218
14219 unsafe impl fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>
14220 for &mut VmoBuffer
14221 {
14222 #[inline]
14223 unsafe fn encode(
14224 self,
14225 encoder: &mut fidl::encoding::Encoder<
14226 '_,
14227 fidl::encoding::DefaultFuchsiaResourceDialect,
14228 >,
14229 offset: usize,
14230 _depth: fidl::encoding::Depth,
14231 ) -> fidl::Result<()> {
14232 encoder.debug_check_bounds::<VmoBuffer>(offset);
14233 // Delegate to tuple encoding.
14234 fidl::encoding::Encode::<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
14235 (
14236 <fidl::encoding::Optional<fidl::encoding::HandleType<fidl::Vmo, { fidl::ObjectType::VMO.into_raw() }, 2147483648>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.vmo),
14237 <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.vmo_usable_start),
14238 ),
14239 encoder, offset, _depth
14240 )
14241 }
14242 }
14243 unsafe impl<
14244 T0: fidl::encoding::Encode<
14245 fidl::encoding::Optional<
14246 fidl::encoding::HandleType<
14247 fidl::Vmo,
14248 { fidl::ObjectType::VMO.into_raw() },
14249 2147483648,
14250 >,
14251 >,
14252 fidl::encoding::DefaultFuchsiaResourceDialect,
14253 >,
14254 T1: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
14255 > fidl::encoding::Encode<VmoBuffer, fidl::encoding::DefaultFuchsiaResourceDialect>
14256 for (T0, T1)
14257 {
14258 #[inline]
14259 unsafe fn encode(
14260 self,
14261 encoder: &mut fidl::encoding::Encoder<
14262 '_,
14263 fidl::encoding::DefaultFuchsiaResourceDialect,
14264 >,
14265 offset: usize,
14266 depth: fidl::encoding::Depth,
14267 ) -> fidl::Result<()> {
14268 encoder.debug_check_bounds::<VmoBuffer>(offset);
14269 // Zero out padding regions. There's no need to apply masks
14270 // because the unmasked parts will be overwritten by fields.
14271 unsafe {
14272 let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
14273 (ptr as *mut u64).write_unaligned(0);
14274 }
14275 // Write the fields.
14276 self.0.encode(encoder, offset + 0, depth)?;
14277 self.1.encode(encoder, offset + 8, depth)?;
14278 Ok(())
14279 }
14280 }
14281
14282 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect> for VmoBuffer {
14283 #[inline(always)]
14284 fn new_empty() -> Self {
14285 Self {
14286 vmo: fidl::new_empty!(
14287 fidl::encoding::Optional<
14288 fidl::encoding::HandleType<
14289 fidl::Vmo,
14290 { fidl::ObjectType::VMO.into_raw() },
14291 2147483648,
14292 >,
14293 >,
14294 fidl::encoding::DefaultFuchsiaResourceDialect
14295 ),
14296 vmo_usable_start: fidl::new_empty!(
14297 u64,
14298 fidl::encoding::DefaultFuchsiaResourceDialect
14299 ),
14300 }
14301 }
14302
14303 #[inline]
14304 unsafe fn decode(
14305 &mut self,
14306 decoder: &mut fidl::encoding::Decoder<
14307 '_,
14308 fidl::encoding::DefaultFuchsiaResourceDialect,
14309 >,
14310 offset: usize,
14311 _depth: fidl::encoding::Depth,
14312 ) -> fidl::Result<()> {
14313 decoder.debug_check_bounds::<Self>(offset);
14314 // Verify that padding bytes are zero.
14315 let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
14316 let padval = unsafe { (ptr as *const u64).read_unaligned() };
14317 let mask = 0xffffffff00000000u64;
14318 let maskedval = padval & mask;
14319 if maskedval != 0 {
14320 return Err(fidl::Error::NonZeroPadding {
14321 padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
14322 });
14323 }
14324 fidl::decode!(
14325 fidl::encoding::Optional<
14326 fidl::encoding::HandleType<
14327 fidl::Vmo,
14328 { fidl::ObjectType::VMO.into_raw() },
14329 2147483648,
14330 >,
14331 >,
14332 fidl::encoding::DefaultFuchsiaResourceDialect,
14333 &mut self.vmo,
14334 decoder,
14335 offset + 0,
14336 _depth
14337 )?;
14338 fidl::decode!(
14339 u64,
14340 fidl::encoding::DefaultFuchsiaResourceDialect,
14341 &mut self.vmo_usable_start,
14342 decoder,
14343 offset + 8,
14344 _depth
14345 )?;
14346 Ok(())
14347 }
14348 }
14349
14350 impl BufferCollectionTokenGroupCreateChildRequest {
14351 #[inline(always)]
14352 fn max_ordinal_present(&self) -> u64 {
14353 if let Some(_) = self.rights_attenuation_mask {
14354 return 2;
14355 }
14356 if let Some(_) = self.token_request {
14357 return 1;
14358 }
14359 0
14360 }
14361 }
14362
14363 impl fidl::encoding::ResourceTypeMarker for BufferCollectionTokenGroupCreateChildRequest {
14364 type Borrowed<'a> = &'a mut Self;
14365 fn take_or_borrow<'a>(
14366 value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
14367 ) -> Self::Borrowed<'a> {
14368 value
14369 }
14370 }
14371
14372 unsafe impl fidl::encoding::TypeMarker for BufferCollectionTokenGroupCreateChildRequest {
14373 type Owned = Self;
14374
14375 #[inline(always)]
14376 fn inline_align(_context: fidl::encoding::Context) -> usize {
14377 8
14378 }
14379
14380 #[inline(always)]
14381 fn inline_size(_context: fidl::encoding::Context) -> usize {
14382 16
14383 }
14384 }
14385
14386 unsafe impl
14387 fidl::encoding::Encode<
14388 BufferCollectionTokenGroupCreateChildRequest,
14389 fidl::encoding::DefaultFuchsiaResourceDialect,
14390 > for &mut BufferCollectionTokenGroupCreateChildRequest
14391 {
14392 unsafe fn encode(
14393 self,
14394 encoder: &mut fidl::encoding::Encoder<
14395 '_,
14396 fidl::encoding::DefaultFuchsiaResourceDialect,
14397 >,
14398 offset: usize,
14399 mut depth: fidl::encoding::Depth,
14400 ) -> fidl::Result<()> {
14401 encoder.debug_check_bounds::<BufferCollectionTokenGroupCreateChildRequest>(offset);
14402 // Vector header
14403 let max_ordinal: u64 = self.max_ordinal_present();
14404 encoder.write_num(max_ordinal, offset);
14405 encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
14406 // Calling encoder.out_of_line_offset(0) is not allowed.
14407 if max_ordinal == 0 {
14408 return Ok(());
14409 }
14410 depth.increment()?;
14411 let envelope_size = 8;
14412 let bytes_len = max_ordinal as usize * envelope_size;
14413 #[allow(unused_variables)]
14414 let offset = encoder.out_of_line_offset(bytes_len);
14415 let mut _prev_end_offset: usize = 0;
14416 if 1 > max_ordinal {
14417 return Ok(());
14418 }
14419
14420 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
14421 // are envelope_size bytes.
14422 let cur_offset: usize = (1 - 1) * envelope_size;
14423
14424 // Zero reserved fields.
14425 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
14426
14427 // Safety:
14428 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
14429 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
14430 // envelope_size bytes, there is always sufficient room.
14431 fidl::encoding::encode_in_envelope_optional::<
14432 fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>>,
14433 fidl::encoding::DefaultFuchsiaResourceDialect,
14434 >(
14435 self.token_request.as_mut().map(
14436 <fidl::encoding::Endpoint<
14437 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14438 > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
14439 ),
14440 encoder,
14441 offset + cur_offset,
14442 depth,
14443 )?;
14444
14445 _prev_end_offset = cur_offset + envelope_size;
14446 if 2 > max_ordinal {
14447 return Ok(());
14448 }
14449
14450 // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
14451 // are envelope_size bytes.
14452 let cur_offset: usize = (2 - 1) * envelope_size;
14453
14454 // Zero reserved fields.
14455 encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
14456
14457 // Safety:
14458 // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
14459 // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
14460 // envelope_size bytes, there is always sufficient room.
14461 fidl::encoding::encode_in_envelope_optional::<
14462 u32,
14463 fidl::encoding::DefaultFuchsiaResourceDialect,
14464 >(
14465 self.rights_attenuation_mask
14466 .as_ref()
14467 .map(<u32 as fidl::encoding::ValueTypeMarker>::borrow),
14468 encoder,
14469 offset + cur_offset,
14470 depth,
14471 )?;
14472
14473 _prev_end_offset = cur_offset + envelope_size;
14474
14475 Ok(())
14476 }
14477 }
14478
14479 impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
14480 for BufferCollectionTokenGroupCreateChildRequest
14481 {
14482 #[inline(always)]
14483 fn new_empty() -> Self {
14484 Self::default()
14485 }
14486
14487 unsafe fn decode(
14488 &mut self,
14489 decoder: &mut fidl::encoding::Decoder<
14490 '_,
14491 fidl::encoding::DefaultFuchsiaResourceDialect,
14492 >,
14493 offset: usize,
14494 mut depth: fidl::encoding::Depth,
14495 ) -> fidl::Result<()> {
14496 decoder.debug_check_bounds::<Self>(offset);
14497 let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
14498 None => return Err(fidl::Error::NotNullable),
14499 Some(len) => len,
14500 };
14501 // Calling decoder.out_of_line_offset(0) is not allowed.
14502 if len == 0 {
14503 return Ok(());
14504 };
14505 depth.increment()?;
14506 let envelope_size = 8;
14507 let bytes_len = len * envelope_size;
14508 let offset = decoder.out_of_line_offset(bytes_len)?;
14509 // Decode the envelope for each type.
14510 let mut _next_ordinal_to_read = 0;
14511 let mut next_offset = offset;
14512 let end_offset = offset + bytes_len;
14513 _next_ordinal_to_read += 1;
14514 if next_offset >= end_offset {
14515 return Ok(());
14516 }
14517
14518 // Decode unknown envelopes for gaps in ordinals.
14519 while _next_ordinal_to_read < 1 {
14520 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14521 _next_ordinal_to_read += 1;
14522 next_offset += envelope_size;
14523 }
14524
14525 let next_out_of_line = decoder.next_out_of_line();
14526 let handles_before = decoder.remaining_handles();
14527 if let Some((inlined, num_bytes, num_handles)) =
14528 fidl::encoding::decode_envelope_header(decoder, next_offset)?
14529 {
14530 let member_inline_size = <fidl::encoding::Endpoint<
14531 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14532 > as fidl::encoding::TypeMarker>::inline_size(
14533 decoder.context
14534 );
14535 if inlined != (member_inline_size <= 4) {
14536 return Err(fidl::Error::InvalidInlineBitInEnvelope);
14537 }
14538 let inner_offset;
14539 let mut inner_depth = depth.clone();
14540 if inlined {
14541 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
14542 inner_offset = next_offset;
14543 } else {
14544 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
14545 inner_depth.increment()?;
14546 }
14547 let val_ref = self.token_request.get_or_insert_with(|| {
14548 fidl::new_empty!(
14549 fidl::encoding::Endpoint<
14550 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14551 >,
14552 fidl::encoding::DefaultFuchsiaResourceDialect
14553 )
14554 });
14555 fidl::decode!(
14556 fidl::encoding::Endpoint<
14557 fidl::endpoints::ServerEnd<BufferCollectionTokenMarker>,
14558 >,
14559 fidl::encoding::DefaultFuchsiaResourceDialect,
14560 val_ref,
14561 decoder,
14562 inner_offset,
14563 inner_depth
14564 )?;
14565 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
14566 {
14567 return Err(fidl::Error::InvalidNumBytesInEnvelope);
14568 }
14569 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
14570 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
14571 }
14572 }
14573
14574 next_offset += envelope_size;
14575 _next_ordinal_to_read += 1;
14576 if next_offset >= end_offset {
14577 return Ok(());
14578 }
14579
14580 // Decode unknown envelopes for gaps in ordinals.
14581 while _next_ordinal_to_read < 2 {
14582 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14583 _next_ordinal_to_read += 1;
14584 next_offset += envelope_size;
14585 }
14586
14587 let next_out_of_line = decoder.next_out_of_line();
14588 let handles_before = decoder.remaining_handles();
14589 if let Some((inlined, num_bytes, num_handles)) =
14590 fidl::encoding::decode_envelope_header(decoder, next_offset)?
14591 {
14592 let member_inline_size =
14593 <u32 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
14594 if inlined != (member_inline_size <= 4) {
14595 return Err(fidl::Error::InvalidInlineBitInEnvelope);
14596 }
14597 let inner_offset;
14598 let mut inner_depth = depth.clone();
14599 if inlined {
14600 decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
14601 inner_offset = next_offset;
14602 } else {
14603 inner_offset = decoder.out_of_line_offset(member_inline_size)?;
14604 inner_depth.increment()?;
14605 }
14606 let val_ref = self.rights_attenuation_mask.get_or_insert_with(|| {
14607 fidl::new_empty!(u32, fidl::encoding::DefaultFuchsiaResourceDialect)
14608 });
14609 fidl::decode!(
14610 u32,
14611 fidl::encoding::DefaultFuchsiaResourceDialect,
14612 val_ref,
14613 decoder,
14614 inner_offset,
14615 inner_depth
14616 )?;
14617 if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
14618 {
14619 return Err(fidl::Error::InvalidNumBytesInEnvelope);
14620 }
14621 if handles_before != decoder.remaining_handles() + (num_handles as usize) {
14622 return Err(fidl::Error::InvalidNumHandlesInEnvelope);
14623 }
14624 }
14625
14626 next_offset += envelope_size;
14627
14628 // Decode the remaining unknown envelopes.
14629 while next_offset < end_offset {
14630 _next_ordinal_to_read += 1;
14631 fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
14632 next_offset += envelope_size;
14633 }
14634
14635 Ok(())
14636 }
14637 }
14638}