1use crate::input_device::{self, Handled, InputDeviceStatus, InputEvent};
6use crate::{Transport, metrics, utils};
7use anyhow::{Error, Result, format_err};
8use async_trait::async_trait;
9use fidl_fuchsia_ui_input3 as fidl_ui_input3;
10use fidl_fuchsia_ui_input3::{KeyEventType, Modifiers};
11use fuchsia_inspect::health::Reporter;
12use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
13use metrics_registry::*;
14
15#[derive(Clone, Debug, PartialEq)]
31pub struct KeyboardEvent {
32 key: fidl_fuchsia_input::Key,
34
35 event_type: KeyEventType,
37
38 modifiers: Option<fidl_ui_input3::Modifiers>,
40
41 lock_state: Option<fidl_ui_input3::LockState>,
43
44 keymap: Option<String>,
47
48 key_meaning: Option<fidl_fuchsia_ui_input3::KeyMeaning>,
53
54 repeat_sequence: u32,
60}
61
62impl KeyboardEvent {
63 pub fn new(key: fidl_fuchsia_input::Key, event_type: KeyEventType) -> Self {
66 KeyboardEvent {
67 key,
68 event_type,
69 modifiers: None,
70 lock_state: None,
71 keymap: None,
72 key_meaning: None,
73 repeat_sequence: 0,
74 }
75 }
76
77 pub fn get_key(&self) -> fidl_fuchsia_input::Key {
78 self.key
79 }
80
81 pub fn into_with_key(self, key: fidl_fuchsia_input::Key) -> Self {
83 Self { key, ..self }
84 }
85
86 pub fn get_event_type(&self) -> KeyEventType {
87 self.event_type
88 }
89
90 pub fn into_with_event_type(self, event_type: KeyEventType) -> Self {
92 Self { event_type, ..self }
93 }
94
95 pub fn into_with_folded_event(self) -> Self {
97 Self { event_type: self.get_event_type_folded(), ..self }
98 }
99
100 pub fn get_event_type_folded(&self) -> KeyEventType {
102 match self.event_type {
103 KeyEventType::Pressed | KeyEventType::Sync => KeyEventType::Pressed,
104 KeyEventType::Released | KeyEventType::Cancel => KeyEventType::Released,
105 }
106 }
107
108 pub fn into_with_modifiers(self, modifiers: Option<fidl_ui_input3::Modifiers>) -> Self {
110 Self { modifiers, ..self }
111 }
112
113 pub fn get_modifiers(&self) -> Option<fidl_ui_input3::Modifiers> {
115 self.modifiers
116 }
117
118 pub fn get_unsided_modifiers(&self) -> Modifiers {
122 let mut modifiers = self.modifiers.unwrap_or(Modifiers::empty());
123 modifiers.set(
124 Modifiers::LEFT_ALT
125 | Modifiers::LEFT_CTRL
126 | Modifiers::LEFT_SHIFT
127 | Modifiers::LEFT_META
128 | Modifiers::RIGHT_ALT
129 | Modifiers::RIGHT_CTRL
130 | Modifiers::RIGHT_SHIFT
131 | Modifiers::RIGHT_META,
132 false,
133 );
134 modifiers
135 }
136
137 pub fn into_with_lock_state(self, lock_state: Option<fidl_ui_input3::LockState>) -> Self {
139 Self { lock_state, ..self }
140 }
141
142 pub fn get_lock_state(&self) -> Option<fidl_ui_input3::LockState> {
144 self.lock_state
145 }
146
147 pub fn into_with_keymap(self, keymap: Option<String>) -> Self {
150 Self { keymap, ..self }
151 }
152
153 pub fn get_keymap(&self) -> Option<String> {
155 self.keymap.clone()
156 }
157
158 pub fn into_with_key_meaning(
160 self,
161 key_meaning: Option<fidl_fuchsia_ui_input3::KeyMeaning>,
162 ) -> Self {
163 Self { key_meaning, ..self }
164 }
165
166 pub fn get_key_meaning(&self) -> Option<fidl_fuchsia_ui_input3::KeyMeaning> {
168 self.key_meaning
169 }
170
171 pub fn get_repeat_sequence(&self) -> u32 {
175 self.repeat_sequence
176 }
177
178 pub fn into_with_repeat_sequence(self, repeat_sequence: u32) -> Self {
181 Self { repeat_sequence, ..self }
182 }
183
184 #[cfg(test)]
186 pub(crate) fn from_key_event_at_time(
187 &self,
188 event_time: zx::MonotonicInstant,
189 ) -> fidl_ui_input3::KeyEvent {
190 fidl_ui_input3::KeyEvent {
191 timestamp: Some(event_time.into_nanos()),
192 type_: Some(self.event_type),
193 key: Some(self.key),
194 modifiers: self.modifiers,
195 lock_state: self.lock_state,
196 repeat_sequence: Some(self.repeat_sequence),
197 key_meaning: self.key_meaning,
198 ..Default::default()
199 }
200 }
201}
202
203impl KeyboardEvent {
204 pub fn same_key(this: &KeyboardEvent, that: &KeyboardEvent) -> bool {
206 this.get_key() == that.get_key()
207 }
208}
209
210#[derive(Clone, Debug, PartialEq)]
212pub struct KeyboardDeviceDescriptor {
213 pub keys: Vec<fidl_fuchsia_input::Key>,
215
216 pub device_information: fidl_fuchsia_input_report::DeviceInformation,
218
219 pub device_id: u32,
221}
222
223#[cfg(test)]
224impl Default for KeyboardDeviceDescriptor {
225 fn default() -> Self {
226 KeyboardDeviceDescriptor {
227 keys: vec![],
228 device_information: fidl_fuchsia_input_report::DeviceInformation {
229 vendor_id: Some(0),
230 product_id: Some(0),
231 version: Some(0),
232 polling_rate: Some(0),
233 ..Default::default()
234 },
235 device_id: 0,
236 }
237 }
238}
239
240pub struct KeyboardBinding {
246 event_sender: UnboundedSender<Vec<InputEvent>>,
248
249 device_descriptor: KeyboardDeviceDescriptor,
251}
252
253#[async_trait]
254impl input_device::InputDeviceBinding for KeyboardBinding {
255 fn input_event_sender(&self) -> UnboundedSender<Vec<InputEvent>> {
256 self.event_sender.clone()
257 }
258
259 fn get_device_descriptor(&self) -> input_device::InputDeviceDescriptor {
260 input_device::InputDeviceDescriptor::Keyboard(self.device_descriptor.clone())
261 }
262}
263
264impl KeyboardBinding {
265 pub async fn new(
280 device_proxy: fidl_next::Client<fidl_next_fuchsia_input_report::InputDevice, Transport>,
281 device_id: u32,
282 input_event_sender: UnboundedSender<Vec<InputEvent>>,
283 device_node: fuchsia_inspect::Node,
284 feature_flags: input_device::InputPipelineFeatureFlags,
285 metrics_logger: metrics::MetricsLogger,
286 ) -> Result<(Self, crate::dispatcher::TaskHandle<()>), Error> {
287 let (device_descriptor, mut inspect_status) =
288 Self::bind_device(&device_proxy, device_id, device_node, metrics_logger.clone())
289 .await?;
290 inspect_status.health_node.set_ok();
291 let task = input_device::initialize_report_stream(
292 device_proxy,
293 input_device::InputDeviceDescriptor::Keyboard(device_descriptor.clone()),
294 input_event_sender.clone(),
295 inspect_status,
296 metrics_logger.clone(),
297 feature_flags,
298 Self::process_reports,
299 );
300
301 Ok((KeyboardBinding { event_sender: input_event_sender, device_descriptor }, task))
302 }
303
304 pub fn to_modifiers(keys: &[&fidl_fuchsia_input::Key]) -> Option<fidl_ui_input3::Modifiers> {
315 let mut modifiers = fidl_ui_input3::Modifiers::empty();
316 for key in keys {
317 let modifier = match key {
318 fidl_fuchsia_input::Key::CapsLock => Some(fidl_ui_input3::Modifiers::CAPS_LOCK),
319 fidl_fuchsia_input::Key::NumLock => Some(fidl_ui_input3::Modifiers::NUM_LOCK),
320 fidl_fuchsia_input::Key::ScrollLock => Some(fidl_ui_input3::Modifiers::SCROLL_LOCK),
321 _ => None,
322 };
323 if let Some(modifier) = modifier {
324 modifiers.insert(modifier);
325 };
326 }
327 if modifiers.is_empty() {
328 return None;
329 }
330 Some(modifiers)
331 }
332
333 async fn bind_device(
344 device: &fidl_next::Client<fidl_next_fuchsia_input_report::InputDevice, Transport>,
345 device_id: u32,
346 device_node: fuchsia_inspect::Node,
347 metrics_logger: metrics::MetricsLogger,
348 ) -> Result<(KeyboardDeviceDescriptor, InputDeviceStatus), Error> {
349 let mut input_device_status = InputDeviceStatus::new(device_node);
350 let descriptor = match device.get_descriptor().await {
351 Ok(descriptor) => descriptor.descriptor,
352 Err(_) => {
353 input_device_status.health_node.set_unhealthy("Could not get device descriptor.");
354 return Err(format_err!("Could not get descriptor for device_id: {}", device_id));
355 }
356 };
357
358 let device_info = descriptor.device_information.ok_or_else(|| {
359 input_device_status.health_node.set_unhealthy("Empty device_information in descriptor");
360 metrics_logger.log_error(
363 InputPipelineErrorMetricDimensionEvent::KeyboardEmptyDeviceInfo,
364 std::format!("DRIVER BUG: empty device_information for device_id: {}", device_id),
365 );
366 format_err!("empty device info for device_id: {}", device_id)
367 })?;
368 match descriptor.keyboard {
369 Some(fidl_next_fuchsia_input_report::KeyboardDescriptor {
370 input: Some(fidl_next_fuchsia_input_report::KeyboardInputDescriptor { keys3, .. }),
371 output: _,
372 ..
373 }) => Ok((
374 KeyboardDeviceDescriptor {
375 keys: keys3
376 .unwrap_or_default()
377 .into_iter()
378 .map(|k| utils::key_to_old(&k))
379 .collect(),
380 device_information: fidl_fuchsia_input_report::DeviceInformation {
381 vendor_id: device_info.vendor_id,
382 product_id: device_info.product_id,
383 version: device_info.version,
384 polling_rate: device_info.polling_rate,
385 ..Default::default()
386 },
387 device_id,
388 },
389 input_device_status,
390 )),
391 device_descriptor => {
392 input_device_status
393 .health_node
394 .set_unhealthy("Keyboard Device Descriptor failed to parse.");
395 Err(format_err!(
396 "Keyboard Device Descriptor failed to parse: \n {:?}",
397 device_descriptor
398 ))
399 }
400 }
401 }
402
403 fn process_reports(
425 reports: &[fidl_next_fuchsia_input_report::wire::InputReport<'_>],
426 mut previous_state: Option<input_device::PreviousDeviceState>,
427 device_descriptor: &input_device::InputDeviceDescriptor,
428 input_event_sender: &mut UnboundedSender<Vec<InputEvent>>,
429 inspect_status: &InputDeviceStatus,
430 metrics_logger: &metrics::MetricsLogger,
431 _feature_flags: &input_device::InputPipelineFeatureFlags,
432 ) -> (Option<input_device::PreviousDeviceState>, Option<UnboundedReceiver<InputEvent>>) {
433 fuchsia_trace::duration!("input", "keyboard-binding-process-report", "num_reports" => reports.len());
434 let (inspect_sender, inspect_receiver) = futures::channel::mpsc::unbounded();
435
436 for report in reports {
437 previous_state = Self::process_report(
438 report,
439 previous_state,
440 device_descriptor,
441 input_event_sender,
442 inspect_status,
443 metrics_logger,
444 inspect_sender.clone(),
445 );
446 }
447 (previous_state, Some(inspect_receiver))
448 }
449
450 fn process_report(
451 report: &fidl_next_fuchsia_input_report::wire::InputReport<'_>,
452 previous_state: Option<input_device::PreviousDeviceState>,
453 device_descriptor: &input_device::InputDeviceDescriptor,
454 input_event_sender: &mut UnboundedSender<Vec<InputEvent>>,
455 inspect_status: &InputDeviceStatus,
456 metrics_logger: &metrics::MetricsLogger,
457 inspect_sender: UnboundedSender<InputEvent>,
458 ) -> Option<input_device::PreviousDeviceState> {
459 if let Some(trace_id) = report.trace_id() {
460 fuchsia_trace::flow_end!("input", "input_report", trace_id.0.into());
461 }
462
463 let tracing_id = fuchsia_trace::Id::new();
464 fuchsia_trace::flow_begin!("input", "key_event_thread", tracing_id);
465
466 inspect_status.count_received_report_wire(report);
467 match report.keyboard() {
469 None => {
470 inspect_status.count_filtered_report();
471 return previous_state;
472 }
473 _ => (),
474 };
475
476 let new_keys = match KeyboardBinding::parse_pressed_keys_wire(report) {
477 Some(keys) => keys,
478 None => {
479 metrics_logger.log_error(
485 InputPipelineErrorMetricDimensionEvent::KeyboardFailedToParse,
486 std::format!("Failed to parse keyboard keys: {:?}", report),
487 );
488 inspect_status.count_filtered_report();
489 return previous_state;
490 }
491 };
492
493 let previous_keys: Vec<fidl_fuchsia_input::Key> = match previous_state {
494 Some(input_device::PreviousDeviceState::Keyboard { pressed_keys }) => pressed_keys,
495 _ => vec![],
496 };
497
498 KeyboardBinding::send_key_events(
499 &new_keys,
500 &previous_keys,
501 device_descriptor.clone(),
502 zx::MonotonicInstant::get(),
503 input_event_sender.clone(),
504 inspect_sender,
505 metrics_logger,
506 tracing_id,
507 );
508
509 Some(input_device::PreviousDeviceState::Keyboard { pressed_keys: new_keys })
510 }
511
512 fn parse_pressed_keys_wire(
513 input_report: &fidl_next_fuchsia_input_report::wire::InputReport<'_>,
514 ) -> Option<Vec<fidl_fuchsia_input::Key>> {
515 input_report
516 .keyboard()
517 .and_then(|unwrapped_keyboard| unwrapped_keyboard.pressed_keys3())
518 .map(|unwrapped_keys| {
519 unwrapped_keys
520 .iter()
521 .map(|&k| {
522 let natural_key = fidl_next::FromWire::from_wire(k);
523 utils::key_to_old(&natural_key)
524 })
525 .collect()
526 })
527 }
528
529 fn send_key_events(
538 new_keys: &Vec<fidl_fuchsia_input::Key>,
539 previous_keys: &Vec<fidl_fuchsia_input::Key>,
540 device_descriptor: input_device::InputDeviceDescriptor,
541 event_time: zx::MonotonicInstant,
542 input_event_sender: UnboundedSender<Vec<InputEvent>>,
543 inspect_sender: UnboundedSender<input_device::InputEvent>,
544 metrics_logger: &metrics::MetricsLogger,
545 tracing_id: fuchsia_trace::Id,
546 ) {
547 fn dispatch_events(
550 key_events: Vec<(fidl_fuchsia_input::Key, fidl_fuchsia_ui_input3::KeyEventType)>,
551 device_descriptor: input_device::InputDeviceDescriptor,
552 event_time: zx::MonotonicInstant,
553 input_event_sender: UnboundedSender<Vec<input_device::InputEvent>>,
554 inspect_sender: UnboundedSender<input_device::InputEvent>,
555 metrics_logger: metrics::MetricsLogger,
556 tracing_id: fuchsia_trace::Id,
557 ) {
558 fuchsia_trace::duration!("input", "key_event_thread");
559 fuchsia_trace::flow_end!("input", "key_event_thread", tracing_id);
560
561 let mut event_time = event_time;
562 for (key, event_type) in key_events.into_iter() {
563 let trace_id = fuchsia_trace::Id::new();
564 fuchsia_trace::duration!("input", "keyboard_event_in_binding");
565 fuchsia_trace::flow_begin!("input", "event_in_input_pipeline", trace_id);
566
567 let event = input_device::InputEvent {
568 device_event: input_device::InputDeviceEvent::Keyboard(KeyboardEvent::new(
569 key, event_type,
570 )),
571 device_descriptor: device_descriptor.clone(),
572 event_time,
573 handled: Handled::No,
574 trace_id: Some(trace_id),
575 };
576 match input_event_sender.unbounded_send(vec![event.clone()]) {
577 Err(error) => {
578 metrics_logger.log_error(
579 InputPipelineErrorMetricDimensionEvent::KeyboardFailedToSendKeyboardEvent,
580 std::format!(
581 "Failed to send KeyboardEvent for key: {:?}, event_type: {:?}: {:?}",
582 key,
583 event_type,
584 error));
585 }
586 _ => {
587 let _ = inspect_sender.unbounded_send(event).expect("Failed to count generated KeyboardEvent in Input Pipeline Inspect tree.");
588 }
589 }
590 event_time = event_time + zx::MonotonicDuration::from_nanos(1);
595 }
596 }
597
598 let pressed_keys = new_keys
601 .iter()
602 .cloned()
603 .filter(|key| !previous_keys.contains(key))
604 .map(|k| (k, fidl_fuchsia_ui_input3::KeyEventType::Pressed));
605
606 let released_keys = previous_keys
609 .iter()
610 .cloned()
611 .filter(|key| !new_keys.contains(key))
612 .map(|k| (k, fidl_fuchsia_ui_input3::KeyEventType::Released));
613
614 let all_keys = released_keys.chain(pressed_keys).collect::<Vec<_>>();
618
619 dispatch_events(
620 all_keys,
621 device_descriptor,
622 event_time,
623 input_event_sender,
624 inspect_sender,
625 metrics_logger.clone(),
626 tracing_id,
627 );
628 }
629}
630
631#[cfg(test)]
632mod tests {
633 use super::*;
634 use crate::testing_utilities;
635 use futures::StreamExt;
636
637 #[fuchsia::test]
640 async fn pressed_key() {
641 let descriptor = input_device::InputDeviceDescriptor::Keyboard(KeyboardDeviceDescriptor {
642 keys: vec![fidl_fuchsia_input::Key::A],
643 ..Default::default()
644 });
645 let (event_time_i64, _) = testing_utilities::event_times();
646
647 let reports = vec![testing_utilities::create_keyboard_input_report(
648 vec![fidl_fuchsia_input::Key::A],
649 event_time_i64,
650 )];
651 let expected_events = vec![testing_utilities::create_keyboard_event(
652 fidl_fuchsia_input::Key::A,
653 fidl_fuchsia_ui_input3::KeyEventType::Pressed,
654 None,
655 &descriptor,
656 None,
657 )];
658
659 assert_input_report_sequence_generates_events!(
660 input_reports: reports,
661 expected_events: expected_events,
662 device_descriptor: descriptor,
663 device_type: KeyboardBinding,
664 );
665 }
666
667 #[fuchsia::test]
670 async fn released_key() {
671 let descriptor = input_device::InputDeviceDescriptor::Keyboard(KeyboardDeviceDescriptor {
672 keys: vec![fidl_fuchsia_input::Key::A],
673 ..Default::default()
674 });
675 let (event_time_i64, _) = testing_utilities::event_times();
676
677 let reports = vec![
678 testing_utilities::create_keyboard_input_report(
679 vec![fidl_fuchsia_input::Key::A],
680 event_time_i64,
681 ),
682 testing_utilities::create_keyboard_input_report(vec![], event_time_i64),
683 ];
684
685 let expected_events = vec![
686 testing_utilities::create_keyboard_event(
687 fidl_fuchsia_input::Key::A,
688 fidl_fuchsia_ui_input3::KeyEventType::Pressed,
689 None,
690 &descriptor,
691 None,
692 ),
693 testing_utilities::create_keyboard_event(
694 fidl_fuchsia_input::Key::A,
695 fidl_fuchsia_ui_input3::KeyEventType::Released,
696 None,
697 &descriptor,
698 None,
699 ),
700 ];
701
702 assert_input_report_sequence_generates_events!(
703 input_reports: reports,
704 expected_events: expected_events,
705 device_descriptor: descriptor.clone(),
706 device_type: KeyboardBinding,
707 );
708 }
709
710 #[fuchsia::test]
713 async fn multiple_pressed_event_filtering() {
714 let descriptor = input_device::InputDeviceDescriptor::Keyboard(KeyboardDeviceDescriptor {
715 keys: vec![fidl_fuchsia_input::Key::A],
716 ..Default::default()
717 });
718 let (event_time_i64, _) = testing_utilities::event_times();
719
720 let reports = vec![
721 testing_utilities::create_keyboard_input_report(
722 vec![fidl_fuchsia_input::Key::A],
723 event_time_i64,
724 ),
725 testing_utilities::create_keyboard_input_report(
726 vec![fidl_fuchsia_input::Key::A],
727 event_time_i64,
728 ),
729 ];
730
731 let expected_events = vec![testing_utilities::create_keyboard_event(
732 fidl_fuchsia_input::Key::A,
733 fidl_fuchsia_ui_input3::KeyEventType::Pressed,
734 None,
735 &descriptor,
736 None,
737 )];
738
739 assert_input_report_sequence_generates_events!(
740 input_reports: reports,
741 expected_events: expected_events,
742 device_descriptor: descriptor,
743 device_type: KeyboardBinding,
744 );
745 }
746
747 #[fuchsia::test]
749 async fn pressed_and_released_keys() {
750 let descriptor = input_device::InputDeviceDescriptor::Keyboard(KeyboardDeviceDescriptor {
751 keys: vec![fidl_fuchsia_input::Key::A, fidl_fuchsia_input::Key::B],
752 ..Default::default()
753 });
754 let (event_time_i64, _) = testing_utilities::event_times();
755
756 let reports = vec![
757 testing_utilities::create_keyboard_input_report(
758 vec![fidl_fuchsia_input::Key::A],
759 event_time_i64,
760 ),
761 testing_utilities::create_keyboard_input_report(
762 vec![fidl_fuchsia_input::Key::B],
763 event_time_i64,
764 ),
765 ];
766
767 let expected_events = vec![
768 testing_utilities::create_keyboard_event(
769 fidl_fuchsia_input::Key::A,
770 fidl_fuchsia_ui_input3::KeyEventType::Pressed,
771 None,
772 &descriptor,
773 None,
774 ),
775 testing_utilities::create_keyboard_event(
776 fidl_fuchsia_input::Key::A,
777 fidl_fuchsia_ui_input3::KeyEventType::Released,
778 None,
779 &descriptor,
780 None,
781 ),
782 testing_utilities::create_keyboard_event(
783 fidl_fuchsia_input::Key::B,
784 fidl_fuchsia_ui_input3::KeyEventType::Pressed,
785 None,
786 &descriptor,
787 None,
788 ),
789 ];
790
791 assert_input_report_sequence_generates_events!(
792 input_reports: reports,
793 expected_events: expected_events,
794 device_descriptor: descriptor,
795 device_type: KeyboardBinding,
796 );
797 }
798
799 #[fuchsia::test]
800 fn get_unsided_modifiers() {
801 use fidl_ui_input3::Modifiers;
802 let event = KeyboardEvent::new(fidl_fuchsia_input::Key::A, KeyEventType::Pressed)
803 .into_with_modifiers(Some(Modifiers::all()));
804 assert_eq!(
805 event.get_unsided_modifiers(),
806 Modifiers::CAPS_LOCK
807 | Modifiers::NUM_LOCK
808 | Modifiers::SCROLL_LOCK
809 | Modifiers::FUNCTION
810 | Modifiers::SYMBOL
811 | Modifiers::SHIFT
812 | Modifiers::ALT
813 | Modifiers::ALT_GRAPH
814 | Modifiers::META
815 | Modifiers::CTRL
816 )
817 }
818
819 #[fuchsia::test]
820 fn conversion_fills_out_all_fields() {
821 use fidl_fuchsia_input::Key;
822 use fidl_ui_input3::{KeyMeaning, LockState, Modifiers, NonPrintableKey};
823 let event = KeyboardEvent::new(Key::A, KeyEventType::Pressed)
824 .into_with_modifiers(Some(Modifiers::all()))
825 .into_with_lock_state(Some(LockState::all()))
826 .into_with_repeat_sequence(42)
827 .into_with_key_meaning(Some(KeyMeaning::NonPrintableKey(NonPrintableKey::Tab)));
828
829 let actual = event.from_key_event_at_time(zx::MonotonicInstant::from_nanos(42));
830 assert_eq!(
831 actual,
832 fidl_fuchsia_ui_input3::KeyEvent {
833 timestamp: Some(42),
834 type_: Some(KeyEventType::Pressed),
835 key: Some(Key::A),
836 modifiers: Some(Modifiers::all()),
837 key_meaning: Some(KeyMeaning::NonPrintableKey(NonPrintableKey::Tab)),
838 repeat_sequence: Some(42),
839 lock_state: Some(LockState::all()),
840 ..Default::default()
841 }
842 );
843 }
844}