From a9f622009ed7d318ed65ee224725190ce6920aaf Mon Sep 17 00:00:00 2001 From: Brindha Senthil Date: Thu, 19 Sep 2024 10:23:03 -0700 Subject: [PATCH 1/8] feat: HDCP/HDR settings cache updated --- core/main/src/service/context_manager.rs | 28 +++++++++++ .../src/events/thunder_event_processor.rs | 21 ++++---- .../events/thunder_event_handlers.rs | 36 +++++++------- .../src/processors/thunder_device_info.rs | 48 +++++++++++++++---- 4 files changed, 98 insertions(+), 35 deletions(-) diff --git a/core/main/src/service/context_manager.rs b/core/main/src/service/context_manager.rs index 38a337fdc..4d4798a85 100644 --- a/core/main/src/service/context_manager.rs +++ b/core/main/src/service/context_manager.rs @@ -75,6 +75,34 @@ impl ContextManager { warn!("No processor to set TimeZoneChanged status listener") } + // Setup the DisplayConnectionChanged status listener + debug!("Subscribing for change in Display Connection"); + if ps + .get_client() + .send_extn_request(DeviceEventRequest { + event: DeviceEvent::InputChanged, + subscribe: true, + callback_type: DeviceEventCallback::ExtnEvent, + }) + .await + .is_err() + { + warn!("No processor to set InputChanged listener") + } + + if ps + .get_client() + .send_extn_request(DeviceEventRequest { + event: DeviceEvent::HdrChanged, + subscribe: true, + callback_type: DeviceEventCallback::ExtnEvent, + }) + .await + .is_err() + { + warn!("No processor to set HdrChanged listener") + } + let ps_c = ps.clone(); // Asynchronously get context and update the state diff --git a/device/thunder_ripple_sdk/src/events/thunder_event_processor.rs b/device/thunder_ripple_sdk/src/events/thunder_event_processor.rs index c58ec68d5..e46f70fa9 100644 --- a/device/thunder_ripple_sdk/src/events/thunder_event_processor.rs +++ b/device/thunder_ripple_sdk/src/events/thunder_event_processor.rs @@ -29,8 +29,8 @@ use ripple_sdk::{ device_events::{DeviceEvent, DeviceEventCallback}, device_operator::DeviceSubscribeRequest, device_request::{ - AudioProfile, InternetConnectionStatus, NetworkResponse, NetworkState, NetworkType, - PowerState, SystemPowerState, VoiceGuidanceState, + AudioProfile, HDCPStatus, InternetConnectionStatus, NetworkResponse, NetworkState, + NetworkType, PowerState, SystemPowerState, VoiceGuidanceState, }, }, }, @@ -43,12 +43,6 @@ use serde::{Deserialize, Serialize}; use crate::{thunder_state::ThunderState, utils::get_audio_profile_from_value}; -#[derive(Debug, Clone, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ActiveInputThunderEvent { - pub active_input: bool, -} - #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TimeZoneChangedThunderEvent { @@ -67,9 +61,16 @@ pub struct ResolutionChangedEvent { pub resolution: String, } +#[derive(Debug, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct DisplayConnectionChangedEvent { + #[serde(rename = "HDCPStatus")] + pub hdcp_status: HDCPStatus, +} + #[derive(Debug, Clone, Deserialize)] pub enum ThunderEventMessage { - ActiveInput(ActiveInputThunderEvent), + DisplayConnection(DisplayConnectionChangedEvent), Resolution(ResolutionChangedEvent), Network(NetworkResponse), Internet(InternetConnectionStatus), @@ -85,7 +86,7 @@ impl ThunderEventMessage { match device_event { DeviceEvent::InputChanged | DeviceEvent::HdrChanged => { if let Ok(v) = serde_json::from_value(value.clone()) { - return Some(ThunderEventMessage::ActiveInput(v)); + return Some(ThunderEventMessage::DisplayConnection(v)); } } DeviceEvent::ScreenResolutionChanged | DeviceEvent::VideoResolutionChanged => { diff --git a/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs b/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs index 6b10156f2..d9fce7504 100644 --- a/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs +++ b/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs @@ -59,8 +59,8 @@ use super::super::thunder_device_info::{ get_dimension_from_resolution, ThunderDeviceInfoRequestProcessor, }; -pub fn is_active_input(value: ThunderEventMessage) -> bool { - if let ThunderEventMessage::ActiveInput(_) = value { +pub fn is_display_connection_changed(value: ThunderEventMessage) -> bool { + if let ThunderEventMessage::DisplayConnection(_) = value { return true; } false @@ -74,7 +74,7 @@ pub fn is_resolution(value: ThunderEventMessage) -> bool { } // ----------------------- -// Active Input Changed +// Display Connection Changed pub struct HDCPEventHandler; impl HDCPEventHandler { @@ -83,14 +83,15 @@ impl HDCPEventHandler { value: ThunderEventMessage, callback_type: DeviceEventCallback, ) { - if let ThunderEventMessage::ActiveInput(input) = value { - if input.active_input { - debug!("activeInput changed"); - } + if let ThunderEventMessage::DisplayConnection(_connection) = value { + debug!("HDCPEventHandler: display connection changed"); } + let state_c = state.clone(); + let cached_state = CachedState::new(state.clone()); + tokio::spawn(async move { - let map = ThunderDeviceInfoRequestProcessor::get_hdcp_support(state).await; + let map = ThunderDeviceInfoRequestProcessor::update_hdcp_cache(cached_state).await; if let Ok(v) = Self::get_extn_event(map, callback_type) { ThunderEventHandler::callback_device_event(state_c, Self::get_mapped_event(), v) } @@ -104,7 +105,7 @@ impl ThunderEventHandlerProvider for HDCPEventHandler { ThunderEventHandler { request: Self::get_device_request(), handle: Self::handle, - is_valid: is_active_input, + is_valid: is_display_connection_changed, listeners: vec![id], id: Self::get_mapped_event(), callback_type, @@ -116,7 +117,7 @@ impl ThunderEventHandlerProvider for HDCPEventHandler { } fn event_name() -> String { - "activeInputChanged".into() + "onDisplayConnectionChanged".into() } fn module() -> String { @@ -135,14 +136,15 @@ impl HDREventHandler { value: ThunderEventMessage, callback_type: DeviceEventCallback, ) { - if let ThunderEventMessage::ActiveInput(input) = value { - if input.active_input { - debug!("activeInput changed"); - } + if let ThunderEventMessage::DisplayConnection(_connection) = value { + debug!("HDREventHandler: display connection changed"); } + let state_c = state.clone(); + let cached_state = CachedState::new(state.clone()); + tokio::spawn(async move { - let map = ThunderDeviceInfoRequestProcessor::get_hdr(state).await; + let map = ThunderDeviceInfoRequestProcessor::get_hdr(cached_state).await; if let Ok(v) = Self::get_extn_event(map, callback_type) { ThunderEventHandler::callback_device_event(state_c, Self::get_mapped_event(), v) } @@ -157,7 +159,7 @@ impl ThunderEventHandlerProvider for HDREventHandler { ThunderEventHandler { request: Self::get_device_request(), handle: Self::handle, - is_valid: is_active_input, + is_valid: is_display_connection_changed, listeners: vec![id], id: Self::get_mapped_event(), callback_type, @@ -169,7 +171,7 @@ impl ThunderEventHandlerProvider for HDREventHandler { } fn event_name() -> String { - "activeInputChanged".into() + "onDisplayConnectionChanged".into() } fn module() -> String { diff --git a/device/thunder_ripple_sdk/src/processors/thunder_device_info.rs b/device/thunder_ripple_sdk/src/processors/thunder_device_info.rs index d79f00aed..44c62ee8a 100644 --- a/device/thunder_ripple_sdk/src/processors/thunder_device_info.rs +++ b/device/thunder_ripple_sdk/src/processors/thunder_device_info.rs @@ -149,6 +149,7 @@ pub struct CachedDeviceInfo { make: Option, hdcp_support: Option>, hdr_profile: Option>, + hdcp_status: Option, version: Option, } @@ -183,6 +184,15 @@ impl CachedState { let _ = hdcp.hdcp_support.insert(value); } + fn get_hdcp_status(&self) -> Option { + self.cached.read().unwrap().hdcp_status.clone() + } + + fn update_hdcp_status(&self, value: HDCPStatus) { + let mut hdcp = self.cached.write().unwrap(); + let _ = hdcp.hdcp_status.insert(value); + } + fn get_hdr(&self) -> Option> { self.cached.read().unwrap().hdr_profile.clone() } @@ -644,7 +654,12 @@ impl ThunderDeviceInfoRequestProcessor { .is_ok() } - pub async fn get_hdcp_support(state: ThunderState) -> HashMap { + pub async fn update_hdcp_cache(state: CachedState) -> HashMap { + Self::get_hdcp_status(&state).await; + Self::get_hdcp_support(state.clone()).await + } + + pub async fn get_hdcp_support(state: CachedState) -> HashMap { let response = state .get_thunder_client() .call(DeviceCallRequest { @@ -679,6 +694,9 @@ impl ThunderDeviceInfoRequestProcessor { hdcp_response.insert(HdcpProfile::Hdcp2_2, is_hdcp_supported); } + // update cache + state.update_hdcp_support(hdcp_response.clone()); + hdcp_response } @@ -686,9 +704,7 @@ impl ThunderDeviceInfoRequestProcessor { if let Some(v) = state.get_hdcp_support() { v } else { - let v = Self::get_hdcp_support(state.clone().state).await; - state.update_hdcp_support(v.clone()); - v + Self::get_hdcp_support(state.clone()).await } } @@ -722,11 +738,23 @@ impl ThunderDeviceInfoRequestProcessor { if let Ok(thdcp) = serde_json::from_value::(resp.message) { response = thdcp.hdcp_status; } + + // update cache + state.update_hdcp_status(response.clone()); + response } + async fn get_cached_hdcp_status(state: &CachedState) -> HDCPStatus { + if let Some(v) = state.get_hdcp_status() { + v + } else { + Self::get_hdcp_status(state).await + } + } + async fn hdcp_status(state: CachedState, req: ExtnMessage) -> bool { - let response = Self::get_hdcp_status(&state).await; + let response = Self::get_cached_hdcp_status(&state).await; Self::respond( state.get_client(), @@ -747,13 +775,13 @@ impl ThunderDeviceInfoRequestProcessor { if let Some(v) = state.get_hdr() { v } else { - let v = Self::get_hdr(state.clone().state).await; + let v = Self::get_hdr(state.clone()).await; state.update_hdr_support(v.clone()); v } } - pub async fn get_hdr(state: ThunderState) -> HashMap { + pub async fn get_hdr(state: CachedState) -> HashMap { let response = state .get_thunder_client() .call(DeviceCallRequest { @@ -787,6 +815,10 @@ impl ThunderDeviceInfoRequestProcessor { HdrProfile::Hdr10plus, 0 != (supported_cap & hdr_flags::HDRSTANDARD_HDR10PLUS), ); + + // update cache + state.update_hdr_support(hm.clone()); + hm } @@ -1392,7 +1424,7 @@ impl ThunderDeviceInfoRequestProcessor { }, async { if device_info_authorized { - Some(Self::get_hdcp_status(&state).await) + Some(Self::get_cached_hdcp_status(&state).await) } else { None } From b7b86467d273ac065859c81b6c9bce2d044f4d77 Mon Sep 17 00:00:00 2001 From: Brindha Senthil Date: Tue, 24 Sep 2024 09:11:01 -0700 Subject: [PATCH 2/8] feat: Updated event handler to clear cache prior to refresh --- .../src/processors/events/thunder_event_handlers.rs | 2 ++ .../src/processors/thunder_device_info.rs | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs b/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs index d9fce7504..9e58ef94b 100644 --- a/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs +++ b/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs @@ -91,6 +91,7 @@ impl HDCPEventHandler { let cached_state = CachedState::new(state.clone()); tokio::spawn(async move { + cached_state.invalidate_hdcp_cache(); let map = ThunderDeviceInfoRequestProcessor::update_hdcp_cache(cached_state).await; if let Ok(v) = Self::get_extn_event(map, callback_type) { ThunderEventHandler::callback_device_event(state_c, Self::get_mapped_event(), v) @@ -144,6 +145,7 @@ impl HDREventHandler { let cached_state = CachedState::new(state.clone()); tokio::spawn(async move { + cached_state.invalidate_hdr_cache(); let map = ThunderDeviceInfoRequestProcessor::get_hdr(cached_state).await; if let Ok(v) = Self::get_extn_event(map, callback_type) { ThunderEventHandler::callback_device_event(state_c, Self::get_mapped_event(), v) diff --git a/device/thunder_ripple_sdk/src/processors/thunder_device_info.rs b/device/thunder_ripple_sdk/src/processors/thunder_device_info.rs index 44c62ee8a..4b847ad3e 100644 --- a/device/thunder_ripple_sdk/src/processors/thunder_device_info.rs +++ b/device/thunder_ripple_sdk/src/processors/thunder_device_info.rs @@ -246,6 +246,17 @@ impl CachedState { let mut cached = self.cached.write().unwrap(); let _ = cached.version.insert(version); } + + pub fn invalidate_hdcp_cache(&self) { + let mut cache = self.cached.write().unwrap(); + cache.hdcp_support = None; + cache.hdcp_status = None; + } + + pub fn invalidate_hdr_cache(&self) { + let mut cache = self.cached.write().unwrap(); + cache.hdr_profile = None; + } } pub struct ThunderNetworkService; From 967e687bfdf541aacba862f95850d0b48f4587b9 Mon Sep 17 00:00:00 2001 From: Brindha Senthil Date: Wed, 25 Sep 2024 09:43:31 -0700 Subject: [PATCH 3/8] feat: Updated code as per review feedback --- core/main/src/firebolt/handlers/device_rpc.rs | 2 +- core/main/src/service/context_manager.rs | 2 +- core/sdk/src/api/device/device_events.rs | 14 +++---- core/sdk/src/api/session.rs | 2 +- core/sdk/src/extn/client/extn_processor.rs | 4 +- device/thunder/src/thunder_ffi.rs | 2 +- .../src/events/thunder_event_processor.rs | 2 +- .../events/thunder_event_handlers.rs | 40 +++++++++---------- .../src/processors/thunder_events.rs | 4 +- 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/core/main/src/firebolt/handlers/device_rpc.rs b/core/main/src/firebolt/handlers/device_rpc.rs index 9f6afe7d0..2a1474750 100644 --- a/core/main/src/firebolt/handlers/device_rpc.rs +++ b/core/main/src/firebolt/handlers/device_rpc.rs @@ -447,7 +447,7 @@ impl DeviceServer for DeviceImpl { .state .get_client() .send_extn_request(DeviceEventRequest { - event: DeviceEvent::InputChanged, + event: DeviceEvent::DisplayChanged, subscribe: listen, callback_type: DeviceEventCallback::FireboltAppEvent(ctx.app_id), }) diff --git a/core/main/src/service/context_manager.rs b/core/main/src/service/context_manager.rs index 4d4798a85..131521c1a 100644 --- a/core/main/src/service/context_manager.rs +++ b/core/main/src/service/context_manager.rs @@ -80,7 +80,7 @@ impl ContextManager { if ps .get_client() .send_extn_request(DeviceEventRequest { - event: DeviceEvent::InputChanged, + event: DeviceEvent::DisplayChanged, subscribe: true, callback_type: DeviceEventCallback::ExtnEvent, }) diff --git a/core/sdk/src/api/device/device_events.rs b/core/sdk/src/api/device/device_events.rs index f1fc33715..586f2473d 100644 --- a/core/sdk/src/api/device/device_events.rs +++ b/core/sdk/src/api/device/device_events.rs @@ -44,7 +44,7 @@ pub const TIME_ZONE_CHANGED: &str = "localization.onTimeZoneChanged"; // Is this from the device to thunder event handler??? #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub enum DeviceEvent { - InputChanged, + DisplayChanged, HdrChanged, ScreenResolutionChanged, VideoResolutionChanged, @@ -61,7 +61,7 @@ impl FromStr for DeviceEvent { fn from_str(s: &str) -> Result { match s { - "device.onHdcpChanged" => Ok(Self::InputChanged), + "device.onHdcpChanged" => Ok(Self::DisplayChanged), "device.onHdrChanged" => Ok(Self::HdrChanged), "device.onScreenResolutionChanged" => Ok(Self::ScreenResolutionChanged), "device.onVideoResolutionChanged" => Ok(Self::VideoResolutionChanged), @@ -112,7 +112,7 @@ impl ExtnPayloadProvider for DeviceEventRequest { } fn get_contract(&self) -> RippleContract { match self.event { - DeviceEvent::InputChanged => RippleContract::DeviceEvents(EventAdjective::Input), + DeviceEvent::DisplayChanged => RippleContract::DeviceEvents(EventAdjective::Hdcp), DeviceEvent::HdrChanged => RippleContract::DeviceEvents(EventAdjective::Hdr), DeviceEvent::ScreenResolutionChanged => { RippleContract::DeviceEvents(EventAdjective::ScreenResolution) @@ -136,7 +136,7 @@ impl ExtnPayloadProvider for DeviceEventRequest { } fn contract() -> RippleContract { - RippleContract::DeviceEvents(EventAdjective::Input) + RippleContract::DeviceEvents(EventAdjective::Hdcp) } } @@ -147,7 +147,7 @@ mod tests { use rstest::rstest; #[rstest(input, expected, - case("device.onHdcpChanged", Ok(DeviceEvent::InputChanged)), + case("device.onHdcpChanged", Ok(DeviceEvent::DisplayChanged)), case("localization.onTimeZoneChanged", Ok(DeviceEvent::TimeZoneChanged)), case("invalid_event", Err(())), )] @@ -168,11 +168,11 @@ mod tests { #[test] fn test_extn_request_device_event() { let device_event_request = DeviceEventRequest { - event: DeviceEvent::InputChanged, + event: DeviceEvent::DisplayChanged, subscribe: true, callback_type: DeviceEventCallback::FireboltAppEvent("id".to_string()), }; - let contract_type: RippleContract = RippleContract::DeviceEvents(EventAdjective::Input); + let contract_type: RippleContract = RippleContract::DeviceEvents(EventAdjective::Hdcp); test_extn_payload_provider(device_event_request, contract_type); } } diff --git a/core/sdk/src/api/session.rs b/core/sdk/src/api/session.rs index 26be1e996..52c28c8f8 100644 --- a/core/sdk/src/api/session.rs +++ b/core/sdk/src/api/session.rs @@ -280,7 +280,7 @@ impl ContractAdjective for SessionAdjective { #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[serde(rename_all = "snake_case")] pub enum EventAdjective { - Input, + Hdcp, Hdr, ScreenResolution, VideoResolution, diff --git a/core/sdk/src/extn/client/extn_processor.rs b/core/sdk/src/extn/client/extn_processor.rs index 5005c81d8..cf5fe97b9 100644 --- a/core/sdk/src/extn/client/extn_processor.rs +++ b/core/sdk/src/extn/client/extn_processor.rs @@ -447,7 +447,7 @@ pub mod tests { contracts: vec![ RippleContract::Internal, RippleContract::Session(SessionAdjective::Device), - RippleContract::DeviceEvents(EventAdjective::Input), + RippleContract::DeviceEvents(EventAdjective::Hdcp), ], }, streamer: DefaultExtnStreamer::new(), @@ -624,7 +624,7 @@ pub mod tests { Some(vec![ RippleContract::Internal, RippleContract::Session(SessionAdjective::Device), - RippleContract::DeviceEvents(EventAdjective::Input), + RippleContract::DeviceEvents(EventAdjective::Hdcp), ]) ); } diff --git a/device/thunder/src/thunder_ffi.rs b/device/thunder/src/thunder_ffi.rs index 7bb355299..18521f512 100644 --- a/device/thunder/src/thunder_ffi.rs +++ b/device/thunder/src/thunder_ffi.rs @@ -46,7 +46,7 @@ fn init_library() -> CExtnMetadata { RippleContract::WindowManager, RippleContract::Browser, RippleContract::RippleContext, - RippleContract::DeviceEvents(EventAdjective::Input), + RippleContract::DeviceEvents(EventAdjective::Hdcp), RippleContract::DeviceEvents(EventAdjective::Hdr), RippleContract::DeviceEvents(EventAdjective::ScreenResolution), RippleContract::DeviceEvents(EventAdjective::VideoResolution), diff --git a/device/thunder_ripple_sdk/src/events/thunder_event_processor.rs b/device/thunder_ripple_sdk/src/events/thunder_event_processor.rs index e46f70fa9..6fb5dd78c 100644 --- a/device/thunder_ripple_sdk/src/events/thunder_event_processor.rs +++ b/device/thunder_ripple_sdk/src/events/thunder_event_processor.rs @@ -84,7 +84,7 @@ impl ThunderEventMessage { pub fn get(event: &str, value: &Value) -> Option { if let Ok(device_event) = DeviceEvent::from_str(event) { match device_event { - DeviceEvent::InputChanged | DeviceEvent::HdrChanged => { + DeviceEvent::DisplayChanged | DeviceEvent::HdrChanged => { if let Ok(v) = serde_json::from_value(value.clone()) { return Some(ThunderEventMessage::DisplayConnection(v)); } diff --git a/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs b/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs index 9e58ef94b..13c801bfe 100644 --- a/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs +++ b/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs @@ -85,18 +85,18 @@ impl HDCPEventHandler { ) { if let ThunderEventMessage::DisplayConnection(_connection) = value { debug!("HDCPEventHandler: display connection changed"); - } - let state_c = state.clone(); - let cached_state = CachedState::new(state.clone()); + let state_c = state.clone(); + let cached_state = CachedState::new(state.clone()); - tokio::spawn(async move { - cached_state.invalidate_hdcp_cache(); - let map = ThunderDeviceInfoRequestProcessor::update_hdcp_cache(cached_state).await; - if let Ok(v) = Self::get_extn_event(map, callback_type) { - ThunderEventHandler::callback_device_event(state_c, Self::get_mapped_event(), v) - } - }); + tokio::spawn(async move { + cached_state.invalidate_hdcp_cache(); + let map = ThunderDeviceInfoRequestProcessor::update_hdcp_cache(cached_state).await; + if let Ok(v) = Self::get_extn_event(map, callback_type) { + ThunderEventHandler::callback_device_event(state_c, Self::get_mapped_event(), v) + } + }); + } } } @@ -139,18 +139,18 @@ impl HDREventHandler { ) { if let ThunderEventMessage::DisplayConnection(_connection) = value { debug!("HDREventHandler: display connection changed"); - } - let state_c = state.clone(); - let cached_state = CachedState::new(state.clone()); + let state_c = state.clone(); + let cached_state = CachedState::new(state.clone()); - tokio::spawn(async move { - cached_state.invalidate_hdr_cache(); - let map = ThunderDeviceInfoRequestProcessor::get_hdr(cached_state).await; - if let Ok(v) = Self::get_extn_event(map, callback_type) { - ThunderEventHandler::callback_device_event(state_c, Self::get_mapped_event(), v) - } - }); + tokio::spawn(async move { + cached_state.invalidate_hdr_cache(); + let map = ThunderDeviceInfoRequestProcessor::get_hdr(cached_state).await; + if let Ok(v) = Self::get_extn_event(map, callback_type) { + ThunderEventHandler::callback_device_event(state_c, Self::get_mapped_event(), v) + } + }); + } } } diff --git a/device/thunder_ripple_sdk/src/processors/thunder_events.rs b/device/thunder_ripple_sdk/src/processors/thunder_events.rs index 9f1b98449..dbe504369 100644 --- a/device/thunder_ripple_sdk/src/processors/thunder_events.rs +++ b/device/thunder_ripple_sdk/src/processors/thunder_events.rs @@ -78,7 +78,7 @@ impl ExtnStreamProcessor for ThunderOpenEventsProcessor { } fn fulfills_mutiple(&self) -> Option> { Some(vec![ - RippleContract::DeviceEvents(EventAdjective::Input), + RippleContract::DeviceEvents(EventAdjective::Hdcp), RippleContract::DeviceEvents(EventAdjective::Hdr), RippleContract::DeviceEvents(EventAdjective::ScreenResolution), RippleContract::DeviceEvents(EventAdjective::VideoResolution), @@ -118,7 +118,7 @@ impl ExtnRequestProcessor for ThunderOpenEventsProcessor { id.clone(), HDREventHandler::provide(id, callback_type), )), - DeviceEvent::InputChanged => Some(state.handle_listener( + DeviceEvent::DisplayChanged => Some(state.handle_listener( listen, id.clone(), HDCPEventHandler::provide(id, callback_type), From 7779b109b87bfa3b61f7e78c8f2369a1da76c178 Mon Sep 17 00:00:00 2001 From: Brindha Senthil Date: Wed, 25 Sep 2024 09:48:54 -0700 Subject: [PATCH 4/8] feat: Updated code --- core/main/src/service/context_manager.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/main/src/service/context_manager.rs b/core/main/src/service/context_manager.rs index 131521c1a..0e8c6cf3b 100644 --- a/core/main/src/service/context_manager.rs +++ b/core/main/src/service/context_manager.rs @@ -87,7 +87,7 @@ impl ContextManager { .await .is_err() { - warn!("No processor to set InputChanged listener") + warn!("No processor to set HdcpChanged listener") } if ps From 67d0a4c86f919d6de129f7f3860dd82ef7d8426f Mon Sep 17 00:00:00 2001 From: Brindha Senthil Date: Fri, 4 Oct 2024 13:57:15 -0700 Subject: [PATCH 5/8] feat: Fixed the event notifications issue --- core/sdk/src/api/context.rs | 138 +++++++++++------- .../src/bootstrap/boot_thunder.rs | 4 +- .../src/client/thunder_client.rs | 54 +++++-- .../events/thunder_event_handlers.rs | 89 ++++++++--- 4 files changed, 197 insertions(+), 88 deletions(-) diff --git a/core/sdk/src/api/context.rs b/core/sdk/src/api/context.rs index accaff84e..5cfd4dd71 100644 --- a/core/sdk/src/api/context.rs +++ b/core/sdk/src/api/context.rs @@ -27,9 +27,12 @@ use crate::{ use serde::{Deserialize, Serialize}; use super::{ - device::device_request::{AccountToken, InternetConnectionStatus, SystemPowerState, TimeZone}, + device::device_request::{ + AccountToken, HdcpProfile, HdrProfile, InternetConnectionStatus, SystemPowerState, TimeZone, + }, firebolt::fb_metrics::MetricsContext, }; +use std::collections::HashMap; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum ActivationStatus { @@ -65,6 +68,8 @@ pub struct RippleContext { pub update_type: Option, pub features: Vec, pub metrics_context: Option, + pub hdcp: Option>, + pub hdr: Option>, } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] @@ -76,26 +81,35 @@ pub enum RippleContextUpdateType { TimeZoneChanged, FeaturesChanged, MetricsContextChanged, + HdcpChanged, + HdrChanged, +} + +#[derive(Default)] +pub struct RippleContextParams { + pub activation_status: Option, + pub internet_connectivity: Option, + pub system_power_state: Option, + pub time_zone: Option, + pub update_type: Option, + pub features: Vec, + pub metrics_context: Option, + pub hdcp: Option>, + pub hdr: Option>, } impl RippleContext { - pub fn new( - activation_status: Option, - internet_connectivity: Option, - system_power_state: Option, - time_zone: Option, - update_type: Option, - features: Vec, - metrics_context: Option, - ) -> RippleContext { + pub fn new(params: RippleContextParams) -> RippleContext { RippleContext { - activation_status, - internet_connectivity, - system_power_state, - time_zone, - update_type, - features, - metrics_context, + activation_status: params.activation_status, + internet_connectivity: params.internet_connectivity, + system_power_state: params.system_power_state, + time_zone: params.time_zone, + update_type: params.update_type, + features: params.features, + metrics_context: params.metrics_context, + hdcp: params.hdcp, + hdr: params.hdr, } } @@ -195,6 +209,26 @@ impl RippleContext { self.update_type = Some(RippleContextUpdateType::MetricsContextChanged); true } + RippleContextUpdateRequest::Hdcp(map) => { + if let Some(h) = self.hdcp.as_ref() { + if h == &map { + return false; + } + } + self.hdcp = Some(map); + self.update_type = Some(RippleContextUpdateType::HdcpChanged); + true + } + RippleContextUpdateRequest::Hdr(map) => { + if let Some(h) = self.hdr.as_ref() { + if h == &map { + return false; + } + } + self.hdr = Some(map); + self.update_type = Some(RippleContextUpdateType::HdrChanged); + true + } } } @@ -204,6 +238,8 @@ impl RippleContext { self.time_zone = context.time_zone; self.features = context.features; self.metrics_context = context.metrics_context; + self.hdcp = context.hdcp; + self.hdr = context.hdr; } pub fn get_event_message(&self) -> ExtnMessage { @@ -223,6 +259,10 @@ impl RippleContext { RippleContextUpdateType::InternetConnectionChanged } else if self.time_zone != context.time_zone { RippleContextUpdateType::TimeZoneChanged + } else if self.hdcp != context.hdcp { + RippleContextUpdateType::HdcpChanged + } else if self.hdr != context.hdr { + RippleContextUpdateType::HdrChanged } else { RippleContextUpdateType::ActivationStatusChanged } @@ -269,6 +309,8 @@ pub enum RippleContextUpdateRequest { UpdateFeatures(Vec), MetricsContext(MetricsContext), RefreshContext(Option), + Hdcp(HashMap), + Hdr(HashMap), } impl RippleContextUpdateRequest { @@ -338,6 +380,8 @@ mod tests { update_type: None, features: Vec::default(), metrics_context: Some(MetricsContext::default()), + hdcp: Some(HashMap::default()), + hdr: Some(HashMap::default()), }; let context2 = RippleContext { @@ -351,6 +395,8 @@ mod tests { update_type: None, features: Vec::default(), metrics_context: Some(MetricsContext::default()), + hdcp: Some(HashMap::default()), + hdr: Some(HashMap::default()), }; assert_eq!( @@ -382,6 +428,8 @@ mod tests { update_type: None, features: Vec::default(), metrics_context: Some(MetricsContext::default()), + hdcp: Some(HashMap::default()), + hdr: Some(HashMap::default()), }; let contract_type: RippleContract = RippleContract::RippleContext; @@ -392,15 +440,11 @@ mod tests { fn test_update_features_enabled_not_exists() { let name = String::from("foo"); let some_other_feature = String::from("bar"); - let mut ripple_context = RippleContext::new( - None, - None, - None, - None, - None, - vec![some_other_feature.clone()], - None, - ); + let params = RippleContextParams { + features: vec![some_other_feature.clone()], + ..Default::default() + }; + let mut ripple_context = RippleContext::new(params); let changed = ripple_context.update(RippleContextUpdateRequest::UpdateFeatures(vec![ FeatureUpdate::new(name.clone(), true), ])); @@ -413,15 +457,11 @@ mod tests { fn test_update_features_enabled_exists() { let name = String::from("foo"); let some_other_feature = String::from("bar"); - let mut ripple_context = RippleContext::new( - None, - None, - None, - None, - None, - vec![some_other_feature.clone()], - None, - ); + let params = RippleContextParams { + features: vec![some_other_feature.clone()], + ..Default::default() + }; + let mut ripple_context = RippleContext::new(params); ripple_context.update(RippleContextUpdateRequest::UpdateFeatures(vec![ FeatureUpdate::new(name.clone(), true), ])); @@ -437,15 +477,11 @@ mod tests { fn test_update_features_disabled_not_exists() { let name = String::from("foo"); let some_other_feature = String::from("bar"); - let mut ripple_context = RippleContext::new( - None, - None, - None, - None, - None, - vec![some_other_feature.clone()], - None, - ); + let params = RippleContextParams { + features: vec![some_other_feature.clone()], + ..Default::default() + }; + let mut ripple_context = RippleContext::new(params); let changed = ripple_context.update(RippleContextUpdateRequest::UpdateFeatures(vec![ FeatureUpdate::new(name.clone(), false), ])); @@ -458,15 +494,11 @@ mod tests { fn test_update_features_disabled_exists() { let name = String::from("foo"); let some_other_feature = String::from("bar"); - let mut ripple_context = RippleContext::new( - None, - None, - None, - None, - None, - vec![some_other_feature.clone()], - None, - ); + let params = RippleContextParams { + features: vec![some_other_feature.clone()], + ..Default::default() + }; + let mut ripple_context = RippleContext::new(params); ripple_context.update(RippleContextUpdateRequest::UpdateFeatures(vec![ FeatureUpdate::new(name.clone(), true), ])); diff --git a/device/thunder_ripple_sdk/src/bootstrap/boot_thunder.rs b/device/thunder_ripple_sdk/src/bootstrap/boot_thunder.rs index 97e443596..61ba1de8b 100644 --- a/device/thunder_ripple_sdk/src/bootstrap/boot_thunder.rs +++ b/device/thunder_ripple_sdk/src/bootstrap/boot_thunder.rs @@ -36,10 +36,10 @@ pub async fn boot_thunder( SetupThunderProcessor::setup(state.clone()).await; return Some(state); } else { - error!("Unable to connect to Thuner, error in ThunderPoolStep"); + error!("Unable to connect to Thunder, error in ThunderPoolStep"); } } else { - error!("Unable to connect to Thuner, error in ThunderGetConfigStep"); + error!("Unable to connect to Thunder, error in ThunderGetConfigStep"); } None } diff --git a/device/thunder_ripple_sdk/src/client/thunder_client.rs b/device/thunder_ripple_sdk/src/client/thunder_client.rs index 99b1036d4..d475487e0 100644 --- a/device/thunder_ripple_sdk/src/client/thunder_client.rs +++ b/device/thunder_ripple_sdk/src/client/thunder_client.rs @@ -242,6 +242,7 @@ impl DeviceOperator for ThunderClient { pub struct ThunderSubscription { handle: JoinHandle<()>, params: Option, + sub_ids_list: HashMap>, listeners: HashMap>, rpc_response: DeviceResponseMessage, } @@ -267,6 +268,11 @@ impl ThunderClient { let mut subscriptions = subscriptions_map.lock().await; if let Some(sub) = subscriptions.get_mut(&subscribe_method) { // rpc subscription already exists, just add a listener + sub.sub_ids_list + .entry(subscribe_method.clone()) + .or_insert_with(Vec::new) + .push(sub_id.clone()); + sub.listeners .insert(sub_id.clone(), thunder_message.handler); if let Some(cb) = thunder_message.callback { @@ -275,11 +281,11 @@ impl ThunderClient { } return; } - // rpc subscription does not exist, set it up - let subscription_res = client - .subscribe_to_method::(subscribe_method.as_str()) - .await; + // rpc subscription does not exist, set it up + let mut sub_ids_list = HashMap::new(); + sub_ids_list.insert(subscribe_method.clone(), vec![sub_id.clone()]); + let subscription_res = client.subscribe_to_method::(&subscribe_method).await; let mut subscription = match subscription_res { Ok(subscription) => subscription, Err(e) => { @@ -310,15 +316,31 @@ impl ThunderClient { }) .send_request(client) .await; - let handler_channel = thunder_message.handler.clone(); - let sub_id_c = sub_id.clone(); + + let subscribe_method_clone = subscribe_method.clone(); + + // Spawn an async task to handle event subscription + let subscriptions_map_clone = Arc::clone(subscriptions_map); let handle = ripple_sdk::tokio::spawn(async move { while let Some(ev_res) = subscription.next().await { match ev_res { Ok(ev) => { - let msg = DeviceResponseMessage::sub(ev, sub_id_c.clone()); - mpsc_send_and_log(&thunder_message.handler, msg, "ThunderSubscribeEvent") - .await; + let mut subscriptions = subscriptions_map_clone.lock().await; + if let Some(sub) = subscriptions.get_mut(&subscribe_method_clone) { + if let Some(sub_id_list) = sub.sub_ids_list.get(&subscribe_method_clone) + { + for sub_id in sub_id_list { + let msg = + DeviceResponseMessage::sub(ev.clone(), sub_id.clone()); + mpsc_send_and_log( + &sub.listeners[sub_id], + msg, + "ThunderSubscribeEvent", + ) + .await; + } + } + } } Err(e) => error!("Thunder event error {e:?}"), } @@ -335,14 +357,20 @@ impl ThunderClient { }); let msg = DeviceResponseMessage::sub(response, sub_id.clone()); - let mut tsub = ThunderSubscription { + let new_subscription = ThunderSubscription { handle, params: thunder_message.params.clone(), - listeners: HashMap::default(), + sub_ids_list, + listeners: { + let mut listeners = HashMap::new(); + listeners.insert(sub_id.clone(), thunder_message.handler.clone()); + listeners + }, rpc_response: msg.clone(), }; - tsub.listeners.insert(sub_id, handler_channel); - subscriptions.insert(subscribe_method, tsub); + + subscriptions.insert(subscribe_method.clone(), new_subscription); + if let Some(cb) = thunder_message.callback { oneshot_send_and_log(cb, msg, "ThunderRegisterResponse"); } diff --git a/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs b/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs index 13c801bfe..9ddac8dcb 100644 --- a/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs +++ b/device/thunder_ripple_sdk/src/processors/events/thunder_event_handlers.rs @@ -25,7 +25,7 @@ use ripple_sdk::api::{ device_events::{ INTERNET_CHANGED_EVENT, TIME_ZONE_CHANGED, VOICE_GUIDANCE_SETTINGS_CHANGED, }, - device_request::{InternetConnectionStatus, TimeZone, VoiceGuidanceState}, + device_request::{HdcpProfile, InternetConnectionStatus, TimeZone, VoiceGuidanceState}, }, }; use ripple_sdk::serde_json; @@ -43,9 +43,7 @@ use crate::{ POWER_STATE_CHANGED, SCREEN_RESOLUTION_CHANGED_EVENT, VIDEO_RESOLUTION_CHANGED_EVENT, }, - device_request::{ - AudioProfile, HdcpProfile, HdrProfile, NetworkResponse, SystemPowerState, - }, + device_request::{AudioProfile, HdrProfile, NetworkResponse, SystemPowerState}, }, extn::extn_client_message::ExtnEvent, log::debug, @@ -81,20 +79,32 @@ impl HDCPEventHandler { pub fn handle( state: ThunderState, value: ThunderEventMessage, - callback_type: DeviceEventCallback, + _callback_type: DeviceEventCallback, ) { if let ThunderEventMessage::DisplayConnection(_connection) = value { debug!("HDCPEventHandler: display connection changed"); - - let state_c = state.clone(); let cached_state = CachedState::new(state.clone()); tokio::spawn(async move { cached_state.invalidate_hdcp_cache(); - let map = ThunderDeviceInfoRequestProcessor::update_hdcp_cache(cached_state).await; - if let Ok(v) = Self::get_extn_event(map, callback_type) { - ThunderEventHandler::callback_device_event(state_c, Self::get_mapped_event(), v) - } + let hdcp = ThunderDeviceInfoRequestProcessor::update_hdcp_cache(cached_state).await; + + let event = ExtnEvent::AppEvent(AppEventRequest::Emit(AppEvent { + event_name: HDCP_CHANGED_EVENT.to_string(), + result: serde_json::to_value(hdcp.clone()).unwrap(), + context: None, + app_id: None, + })); + ThunderEventHandler::callback_device_event( + state.clone(), + HDCP_CHANGED_EVENT.to_string(), + event, + ); + + ThunderEventHandler::callback_context_update( + state, + RippleContextUpdateRequest::Hdcp(hdcp), + ); }); } } @@ -122,7 +132,27 @@ impl ThunderEventHandlerProvider for HDCPEventHandler { } fn module() -> String { - ThunderPlugin::DisplaySettings.callsign_string() + ThunderPlugin::Hdcp.callsign_string() + } + + fn get_id(&self) -> String { + Self::get_mapped_event() + } + + fn get_device_request() -> ripple_sdk::api::device::device_operator::DeviceSubscribeRequest { + ripple_sdk::api::device::device_operator::DeviceSubscribeRequest { + module: Self::module(), + event_name: Self::event_name(), + params: None, + sub_id: Some(Self::get_mapped_event()), + } + } + + fn get_extn_event( + _r: Self::EVENT, + _callback_type: DeviceEventCallback, + ) -> Result { + Err(RippleError::InvalidOutput) } } @@ -135,20 +165,32 @@ impl HDREventHandler { pub fn handle( state: ThunderState, value: ThunderEventMessage, - callback_type: DeviceEventCallback, + _callback_type: DeviceEventCallback, ) { if let ThunderEventMessage::DisplayConnection(_connection) = value { debug!("HDREventHandler: display connection changed"); - - let state_c = state.clone(); let cached_state = CachedState::new(state.clone()); tokio::spawn(async move { cached_state.invalidate_hdr_cache(); - let map = ThunderDeviceInfoRequestProcessor::get_hdr(cached_state).await; - if let Ok(v) = Self::get_extn_event(map, callback_type) { - ThunderEventHandler::callback_device_event(state_c, Self::get_mapped_event(), v) - } + let hdr = ThunderDeviceInfoRequestProcessor::get_hdr(cached_state).await; + + let event = ExtnEvent::AppEvent(AppEventRequest::Emit(AppEvent { + event_name: HDR_CHANGED_EVENT.to_string(), + result: serde_json::to_value(hdr.clone()).unwrap(), + context: None, + app_id: None, + })); + ThunderEventHandler::callback_device_event( + state.clone(), + HDR_CHANGED_EVENT.to_string(), + event, + ); + + ThunderEventHandler::callback_context_update( + state, + RippleContextUpdateRequest::Hdr(hdr), + ); }); } } @@ -177,7 +219,14 @@ impl ThunderEventHandlerProvider for HDREventHandler { } fn module() -> String { - ThunderPlugin::DisplaySettings.callsign_string() + ThunderPlugin::Hdcp.callsign_string() + } + + fn get_extn_event( + _r: Self::EVENT, + _callback_type: DeviceEventCallback, + ) -> Result { + Err(RippleError::InvalidOutput) } } From a1ae8de2fc86454e493b27a887ab6fd2a937ff69 Mon Sep 17 00:00:00 2001 From: Brindha Senthil Date: Fri, 4 Oct 2024 14:06:55 -0700 Subject: [PATCH 6/8] feat: code cleanup --- core/sdk/src/api/context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sdk/src/api/context.rs b/core/sdk/src/api/context.rs index 5cfd4dd71..2735a7139 100644 --- a/core/sdk/src/api/context.rs +++ b/core/sdk/src/api/context.rs @@ -34,7 +34,7 @@ use super::{ }; use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum ActivationStatus { NotActivated, AccountToken(AccountToken), From fa665ada0917c0e911c0798bb68cbbba4afbd025 Mon Sep 17 00:00:00 2001 From: Brindha Senthil Date: Mon, 7 Oct 2024 11:47:53 -0700 Subject: [PATCH 7/8] feat: Updated unsubscribe to remove the sub_id from list. --- device/thunder_ripple_sdk/src/client/thunder_client.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/device/thunder_ripple_sdk/src/client/thunder_client.rs b/device/thunder_ripple_sdk/src/client/thunder_client.rs index d475487e0..992d3f5fa 100644 --- a/device/thunder_ripple_sdk/src/client/thunder_client.rs +++ b/device/thunder_ripple_sdk/src/client/thunder_client.rs @@ -392,7 +392,15 @@ impl ThunderClient { // unsubscribe through rpc let mut subscriptions = subscriptions_map.lock().await; if let Some(sub) = subscriptions.get_mut(&subscribe_method) { + // Remove the listener for the given sub_id sub.listeners.remove(&sub_id); + + sub.sub_ids_list.get_mut(&subscribe_method).map(|sub_ids| { + // Remove the sub_id from the list of sub_ids + sub_ids.retain(|id| id != &sub_id); + }); + + // Check if there are any listeners left if sub.listeners.is_empty() { unregister = true; if let Some(s) = subscriptions.remove(&subscribe_method) { From 2d20577b8505454e64939c95e67c7ede88d13efa Mon Sep 17 00:00:00 2001 From: Brindha Senthil Date: Mon, 7 Oct 2024 12:30:03 -0700 Subject: [PATCH 8/8] feat: Fixed clippy error --- device/thunder_ripple_sdk/src/client/thunder_client.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/device/thunder_ripple_sdk/src/client/thunder_client.rs b/device/thunder_ripple_sdk/src/client/thunder_client.rs index 992d3f5fa..5a559e4a7 100644 --- a/device/thunder_ripple_sdk/src/client/thunder_client.rs +++ b/device/thunder_ripple_sdk/src/client/thunder_client.rs @@ -394,11 +394,11 @@ impl ThunderClient { if let Some(sub) = subscriptions.get_mut(&subscribe_method) { // Remove the listener for the given sub_id sub.listeners.remove(&sub_id); - - sub.sub_ids_list.get_mut(&subscribe_method).map(|sub_ids| { - // Remove the sub_id from the list of sub_ids + + // Remove the sub_id from the list of sub_ids + if let Some(sub_ids) = sub.sub_ids_list.get_mut(&subscribe_method) { sub_ids.retain(|id| id != &sub_id); - }); + } // Check if there are any listeners left if sub.listeners.is_empty() {