1616
1717use std:: { iter, time:: Duration } ;
1818
19- use driver_req:: UpdateDelayedEventRequest ;
20- use from_widget:: UpdateDelayedEventResponse ;
19+ use driver_req:: { SendToDeviceRequest , UpdateDelayedEventRequest } ;
20+ use from_widget:: { SendToDeviceEventResponse , UpdateDelayedEventResponse } ;
2121use indexmap:: IndexMap ;
2222use ruma:: {
2323 serde:: { JsonObject , Raw } ,
@@ -41,15 +41,16 @@ use self::{
4141 openid:: { OpenIdResponse , OpenIdState } ,
4242 pending:: { PendingRequests , RequestLimits } ,
4343 to_widget:: {
44- NotifyCapabilitiesChanged , NotifyNewMatrixEvent , NotifyOpenIdChanged , RequestCapabilities ,
45- ToWidgetRequest , ToWidgetRequestHandle , ToWidgetResponse ,
44+ NotifyCapabilitiesChanged , NotifyNewMatrixEvent , NotifyNewToDeviceEvent ,
45+ NotifyOpenIdChanged , RequestCapabilities , ToWidgetRequest , ToWidgetRequestHandle ,
46+ ToWidgetResponse ,
4647 } ,
4748} ;
4849#[ cfg( doc) ]
4950use super :: WidgetDriver ;
5051use super :: {
5152 capabilities:: { SEND_DELAYED_EVENT , UPDATE_DELAYED_EVENT } ,
52- filter:: FilterInput ,
53+ filter:: { FilterInput , FilterInputToDevice } ,
5354 Capabilities , StateKeySelector ,
5455} ;
5556use crate :: Result ;
@@ -179,6 +180,25 @@ impl WidgetMachine {
179180 }
180181 Vec :: new ( )
181182 }
183+ IncomingMessage :: ToDeviceReceived ( to_device_raw) => {
184+ let CapabilitiesState :: Negotiated ( capabilities) = & self . capabilities else {
185+ error ! ( "Received to device event before capabilities negotiation" ) ;
186+ return Vec :: new ( ) ;
187+ } ;
188+ let event_filter_in = match to_device_raw. clone ( ) . try_into ( ) {
189+ Ok ( filter_in) => filter_in,
190+ Err ( e) => {
191+ error ! ( "Failed to convert to device event to filter input: {e}" ) ;
192+ return Vec :: new ( ) ;
193+ }
194+ } ;
195+ if capabilities. allow_reading ( & event_filter_in) {
196+ let action =
197+ self . send_to_widget_request ( NotifyNewToDeviceEvent ( to_device_raw) ) . 1 ;
198+ return action. map ( |a| vec ! [ a] ) . unwrap_or_default ( ) ;
199+ }
200+ Vec :: new ( )
201+ }
182202 }
183203 }
184204
@@ -247,6 +267,11 @@ impl WidgetMachine {
247267 . map ( |a| vec ! [ a] )
248268 . unwrap_or_default ( ) ,
249269
270+ FromWidgetRequest :: SendToDevice ( req) => self
271+ . process_to_device_request ( req, raw_request)
272+ . map ( |a| vec ! [ a] )
273+ . unwrap_or_default ( ) ,
274+
250275 FromWidgetRequest :: GetOpenId { } => {
251276 let ( request, request_action) = self . send_matrix_driver_request ( RequestOpenId ) ;
252277 request. then ( |res, machine| {
@@ -425,7 +450,38 @@ impl WidgetMachine {
425450 result. map_err( FromWidgetErrorResponse :: from_error) ,
426451 ) ]
427452 } ) ;
453+ action
454+ }
455+
456+ fn process_to_device_request (
457+ & mut self ,
458+ request : SendToDeviceRequest ,
459+ raw_request : Raw < FromWidgetRequest > ,
460+ ) -> Option < Action > {
461+ let CapabilitiesState :: Negotiated ( capabilities) = & self . capabilities else {
462+ error ! ( "Received send event request before capabilities negotiation" ) ;
463+ return None ;
464+ } ;
465+
466+ let filter_in =
467+ FilterInput :: ToDevice ( FilterInputToDevice { event_type : request. event_type . clone ( ) } ) ;
428468
469+ if !capabilities. allow_sending ( & filter_in) {
470+ return Some ( Self :: send_from_widget_error_string_response (
471+ raw_request,
472+ format ! ( "Not allowed to send to-device message of type: {}" , request. event_type) ,
473+ ) ) ;
474+ }
475+
476+ let ( request, action) = self . send_matrix_driver_request ( request) ;
477+ request. then ( |result, _| {
478+ vec ! [ Self :: send_from_widget_response(
479+ raw_request,
480+ result
481+ . map( Into :: <SendToDeviceEventResponse >:: into)
482+ . map_err( FromWidgetErrorResponse :: from_error) ,
483+ ) ]
484+ } ) ;
429485 action
430486 }
431487
0 commit comments