29 #include "dsMgrProductTraitsHandler.h"
33 using namespace dsMgrProductTraits;
34 extern bool isTVOperatingInFactory();
35 extern int _SetAVPortsPowerState(IARM_Bus_PWRMgr_PowerState_t powerState);
36 extern IARM_Result_t _dsSetFPState(
void *arg);
45 const unsigned int REBOOT_REASON_RETRY_INTERVAL_SECONDS = 2;
47 static reboot_type_t getRebootType()
49 const char * file_updated_flag =
"/tmp/Update_rebootInfo_invoked";
50 const char * reboot_info_file_name =
"/opt/secure/reboot/previousreboot.info";
51 const char * hard_reboot_match_string = R
"("reason":"POWER_ON_RESET")";
52 reboot_type_t ret = reboot_type_t::SOFT;
55 if(0 != access(file_updated_flag, F_OK))
57 INT_DEBUG(
"%s: Error! Reboot info file isn't updated yet.\n", __func__);
58 ret = reboot_type_t::UNAVAILABLE;
62 std::ifstream reboot_info_file(reboot_info_file_name);
64 if (
true == reboot_info_file.is_open())
66 while(std::getline(reboot_info_file, line))
68 if(std::string::npos != line.find(hard_reboot_match_string))
70 INT_DEBUG(
"%s: Detected hard reboot.\n", __func__);
71 ret = reboot_type_t::HARD;
77 INT_DEBUG(
"%s: Failed to open file\n", __func__);
82 static gboolean reboot_reason_cb(gpointer data)
84 static unsigned int count = 0;
85 constexpr
unsigned int max_count = 120 / REBOOT_REASON_RETRY_INTERVAL_SECONDS;
87 reboot_type_t reboot_type = getRebootType();
88 if(reboot_type_t::UNAVAILABLE == reboot_type)
90 if(max_count >= count++)
92 return G_SOURCE_CONTINUE;
96 INT_DEBUG(
"%s: Exceeded retry limit.\n", __func__);
97 return G_SOURCE_REMOVE;
102 INT_DEBUG(
"%s: Got reboot reason in async check. Applying display configuration.\n", __func__);
104 ptr->sync_display_ports_with_reboot_reason(reboot_type);
105 return G_SOURCE_REMOVE;
109 static inline bool doForceDisplayOnPostReboot()
111 const char * flag_filename =
"/opt/force_display_on_after_reboot";
113 if(0 == access(flag_filename, F_OK))
115 INT_DEBUG(
"%s: %s\n", __func__, (
true == ret ?
"true" :
"false"));
119 namespace dsMgrProductTraits
123 bool ux_controller::set_bootloader_pattern(mfrBlPattern_t pattern)
126 invalidateAsyncBootloaderPattern =
true;
128 return _set_bootloader_pattern(pattern);
131 bool ux_controller::_set_bootloader_pattern(mfrBlPattern_t pattern)
const
135 if (
false == enableSilentRebootSupport)
139 mfrparam.pattern = pattern;
142 INT_DEBUG(
"Warning! Call to IARM_BUS_MFRLIB_API_SetBootLoaderPattern failed.\n");
147 INT_DEBUG(
"%s: successfully set pattern %d\n", __func__, (
int) pattern);
151 void ux_controller::_set_bootloader_pattern_async(mfrBlPattern_t pattern)
const
154 const unsigned int retry_interval_seconds = 5;
155 unsigned int remaining_retries = 12;
156 INT_DEBUG(
"%s start for pattern 0x%x\n", __func__, pattern);
159 std::this_thread::sleep_for(std::chrono::seconds(retry_interval_seconds));
160 std::unique_lock <std::mutex> lock (mutex);
161 if(
false == invalidateAsyncBootloaderPattern)
163 ret = _set_bootloader_pattern(pattern);
167 INT_DEBUG(
"%s: bootloader pattern invalidated. Aborting.\n", __func__);
171 }
while ((
false == ret) && (0 < --remaining_retries));
174 INT_DEBUG(
"%s returns.\n", __func__);
177 bool ux_controller::set_bootloader_pattern_fault_tolerant(mfrBlPattern_t pattern)
182 ret = _set_bootloader_pattern(pattern);
187 invalidateAsyncBootloaderPattern =
false;
189 std::thread retry_thread(&ux_controller::_set_bootloader_pattern_async,
this, pattern);
190 retry_thread.detach();
195 ux_controller::ux_controller(
unsigned int in_id,
const std::string &in_name, deviceType_t in_deviceType) : id(in_id), name(in_name), deviceType(in_deviceType)
197 INT_DEBUG(
"%s: initializing for profile id %d, name %s\n", __func__,
id, name.c_str());
198 initialize_safe_defaults();
201 void ux_controller::initialize_safe_defaults()
203 enableMultiColourLedSupport =
false;
204 enableSilentRebootSupport =
true;
205 preferedPowerModeOnReboot = POWER_MODE_LAST_KNOWN;
206 invalidateAsyncBootloaderPattern =
false;
207 firstPowerTransitionComplete =
false;
209 if (DEVICE_TYPE_STB == deviceType)
211 ledEnabledInStandby =
false;
212 ledEnabledInOnState =
true;
216 ledEnabledInStandby =
true;
217 ledEnabledInOnState =
true;
221 void ux_controller::sync_power_led_with_power_state(IARM_Bus_PWRMgr_PowerState_t power_state)
const
223 if (
true == enableMultiColourLedSupport)
225 INT_DEBUG(
"Warning! Device supports multi-colour LEDs but it isn't handled.");
229 if (IARM_BUS_PWRMGR_POWERSTATE_ON == power_state)
230 led_state = ledEnabledInOnState;
232 led_state = ledEnabledInStandby;
236 INT_DEBUG(
"%s: setting power LED State to %s\n", __func__, (led_state ?
"ON" :
"FALSE"));
240 _dsSetFPState(¶m);
244 INT_DEBUG(
"%s: Warning! exception caught when trying to change FP state\n", __func__);
248 void ux_controller::sync_display_ports_with_power_state(IARM_Bus_PWRMgr_PowerState_t power_state)
const
250 _SetAVPortsPowerState(power_state);
252 bool ux_controller::initialize_ux_controller(
unsigned int profile_id)
257 case DEFAULT_STB_PROFILE:
261 case DEFAULT_TV_PROFILE:
265 case DEFAULT_STB_PROFILE_EUROPE:
269 case DEFAULT_TV_PROFILE_EUROPE:
274 INT_DEBUG(
"Error! Unsupported product profile id %d\n", profile_id);
292 ux_controller_tv_eu::ux_controller_tv_eu(
unsigned int in_id,
const std::string &in_name) :
ux_controller(in_id, in_name, DEVICE_TYPE_TV)
294 preferedPowerModeOnReboot = POWER_MODE_LIGHT_SLEEP;
297 bool ux_controller_tv_eu::applyPowerStateChangeConfig(IARM_Bus_PWRMgr_PowerState_t new_state, IARM_Bus_PWRMgr_PowerState_t prev_state)
300 sync_display_ports_with_power_state(new_state);
301 ret = set_bootloader_pattern((IARM_BUS_PWRMGR_POWERSTATE_ON == new_state ? mfrBL_PATTERN_NORMAL : mfrBL_PATTERN_SILENT_LED_ON));
305 bool ux_controller_tv_eu::applyPreRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
const
309 bool ux_controller_tv_eu::applyPreMaintenanceRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
312 if (IARM_BUS_PWRMGR_POWERSTATE_ON != current_state)
314 ret = set_bootloader_pattern(mfrBL_PATTERN_SILENT);
319 bool ux_controller_tv_eu::applyPostRebootConfig(IARM_Bus_PWRMgr_PowerState_t target_state, IARM_Bus_PWRMgr_PowerState_t last_known_state )
325 if ((IARM_BUS_PWRMGR_POWERSTATE_ON == last_known_state) && (IARM_BUS_PWRMGR_POWERSTATE_STANDBY == target_state))
329 sync_display_ports_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_ON);
333 sync_display_ports_with_power_state(target_state);
340 mfrBlPattern_t pattern = mfrBL_PATTERN_NORMAL;
341 switch (target_state)
343 case IARM_BUS_PWRMGR_POWERSTATE_ON:
347 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY:
348 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY_LIGHT_SLEEP:
349 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP:
350 pattern = mfrBL_PATTERN_SILENT_LED_ON;
353 INT_DEBUG(
"%s: Warning! Unhandled power transition. New state: %d\n", __func__, target_state);
356 ret = set_bootloader_pattern_fault_tolerant(pattern);
360 IARM_Bus_PWRMgr_PowerState_t ux_controller_tv_eu::getPreferredPostRebootPowerState(IARM_Bus_PWRMgr_PowerState_t prev_state)
const
362 return IARM_BUS_PWRMGR_POWERSTATE_STANDBY;
370 ux_controller_stb_eu::ux_controller_stb_eu(
unsigned int in_id,
const std::string &in_name) :
ux_controller(in_id, in_name, DEVICE_TYPE_STB)
372 preferedPowerModeOnReboot = POWER_MODE_LIGHT_SLEEP;
375 bool ux_controller_stb_eu::applyPowerStateChangeConfig(IARM_Bus_PWRMgr_PowerState_t new_state, IARM_Bus_PWRMgr_PowerState_t prev_state)
377 sync_display_ports_with_power_state(new_state);
378 sync_power_led_with_power_state(new_state);
382 bool ux_controller_stb_eu::applyPreRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
const
386 bool ux_controller_stb_eu::applyPreMaintenanceRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
389 if (IARM_BUS_PWRMGR_POWERSTATE_ON != current_state)
391 ret = set_bootloader_pattern(mfrBL_PATTERN_SILENT);
396 bool ux_controller_stb_eu::applyPostRebootConfig(IARM_Bus_PWRMgr_PowerState_t target_state, IARM_Bus_PWRMgr_PowerState_t last_known_state )
399 if ((IARM_BUS_PWRMGR_POWERSTATE_ON == last_known_state) && (IARM_BUS_PWRMGR_POWERSTATE_STANDBY == target_state))
402 sync_power_led_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_ON);
403 sync_display_ports_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_ON);
407 sync_power_led_with_power_state(target_state);
408 sync_display_ports_with_power_state(target_state);
412 ret = set_bootloader_pattern_fault_tolerant(mfrBL_PATTERN_NORMAL);
416 IARM_Bus_PWRMgr_PowerState_t ux_controller_stb_eu::getPreferredPostRebootPowerState(IARM_Bus_PWRMgr_PowerState_t prev_state)
const
418 return IARM_BUS_PWRMGR_POWERSTATE_STANDBY;
425 ux_controller_tv::ux_controller_tv(
unsigned int in_id,
const std::string &in_name) :
ux_controller(in_id, in_name, DEVICE_TYPE_TV)
427 preferedPowerModeOnReboot = POWER_MODE_LIGHT_SLEEP;
430 bool ux_controller_tv::applyPowerStateChangeConfig(IARM_Bus_PWRMgr_PowerState_t new_state, IARM_Bus_PWRMgr_PowerState_t prev_state)
433 if(
false == firstPowerTransitionComplete)
434 firstPowerTransitionComplete =
true;
438 sync_display_ports_with_power_state(new_state);
439 bool ret = set_bootloader_pattern((IARM_BUS_PWRMGR_POWERSTATE_ON == new_state ? mfrBL_PATTERN_NORMAL : mfrBL_PATTERN_SILENT_LED_ON));
443 bool ux_controller_tv::applyPreRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
const
447 bool ux_controller_tv::applyPreMaintenanceRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
450 if (IARM_BUS_PWRMGR_POWERSTATE_ON != current_state)
452 ret = set_bootloader_pattern(mfrBL_PATTERN_SILENT_LED_ON);
457 bool ux_controller_tv::applyPostRebootConfig(IARM_Bus_PWRMgr_PowerState_t target_state, IARM_Bus_PWRMgr_PowerState_t last_known_state )
460 sync_power_led_with_power_state(target_state);
462 if ((IARM_BUS_PWRMGR_POWERSTATE_ON == last_known_state) && (IARM_BUS_PWRMGR_POWERSTATE_STANDBY == target_state))
476 if(
true == doForceDisplayOnPostReboot() || (
true == isTVOperatingInFactory()))
477 sync_display_ports_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_ON);
480 reboot_type_t isHardReboot = getRebootType();
481 switch (isHardReboot)
483 case reboot_type_t::HARD:
484 sync_display_ports_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_STANDBY);
487 case reboot_type_t::SOFT:
488 sync_display_ports_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_ON);
492 g_timeout_add_seconds(REBOOT_REASON_RETRY_INTERVAL_SECONDS, reboot_reason_cb,
this);
499 sync_display_ports_with_power_state(target_state);
506 mfrBlPattern_t pattern = mfrBL_PATTERN_NORMAL;
507 switch (target_state)
509 case IARM_BUS_PWRMGR_POWERSTATE_ON:
513 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY:
514 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY_LIGHT_SLEEP:
515 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP:
516 pattern = mfrBL_PATTERN_SILENT_LED_ON;
519 INT_DEBUG(
"%s: Warning! Unhandled power transition. New state: %d\n", __func__, target_state);
522 ret = set_bootloader_pattern_fault_tolerant(pattern);
526 IARM_Bus_PWRMgr_PowerState_t ux_controller_tv::getPreferredPostRebootPowerState(IARM_Bus_PWRMgr_PowerState_t prev_state)
const
528 return IARM_BUS_PWRMGR_POWERSTATE_STANDBY;
531 void ux_controller_tv::sync_display_ports_with_reboot_reason(reboot_type_t reboot_type)
535 if(
false == firstPowerTransitionComplete)
538 sync_display_ports_with_power_state(reboot_type_t::HARD == reboot_type? IARM_BUS_PWRMGR_POWERSTATE_STANDBY : IARM_BUS_PWRMGR_POWERSTATE_ON);
548 ux_controller_stb::ux_controller_stb(
unsigned int in_id,
const std::string &in_name) :
ux_controller(in_id, in_name, DEVICE_TYPE_STB)
550 preferedPowerModeOnReboot = POWER_MODE_LAST_KNOWN;
551 enableSilentRebootSupport =
false;
554 bool ux_controller_stb::applyPowerStateChangeConfig(IARM_Bus_PWRMgr_PowerState_t new_state, IARM_Bus_PWRMgr_PowerState_t prev_state)
556 sync_display_ports_with_power_state(new_state);
557 sync_power_led_with_power_state(new_state);
561 bool ux_controller_stb::applyPreRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
const
565 bool ux_controller_stb::applyPreMaintenanceRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
571 bool ux_controller_stb::applyPostRebootConfig(IARM_Bus_PWRMgr_PowerState_t target_state, IARM_Bus_PWRMgr_PowerState_t last_known_state )
574 sync_power_led_with_power_state(target_state);
575 sync_display_ports_with_power_state(target_state);
579 IARM_Bus_PWRMgr_PowerState_t ux_controller_stb::getPreferredPostRebootPowerState(IARM_Bus_PWRMgr_PowerState_t prev_state)
const