26 #include "pwrlogger.h"
29 #include "productTraits.h"
32 using namespace pwrMgrProductTraits;
33 extern bool isTVOperatingInFactory();
34 extern int _SetAVPortsPowerState(IARM_Bus_PWRMgr_PowerState_t powerState);
42 const unsigned int REBOOT_REASON_RETRY_INTERVAL_SECONDS = 2;
44 static reboot_type_t getRebootType()
46 const char * file_updated_flag =
"/tmp/Update_rebootInfo_invoked";
47 const char * reboot_info_file_name =
"/opt/secure/reboot/previousreboot.info";
48 const char * hard_reboot_match_string = R
"("reason":"POWER_ON_RESET")";
49 reboot_type_t ret = reboot_type_t::SOFT;
52 if(0 != access(file_updated_flag, F_OK))
54 LOG(
"%s: Error! Reboot info file isn't updated yet.\n", __func__);
55 ret = reboot_type_t::UNAVAILABLE;
59 std::ifstream reboot_info_file(reboot_info_file_name);
61 if (
true == reboot_info_file.is_open())
63 while(std::getline(reboot_info_file, line))
65 if(std::string::npos != line.find(hard_reboot_match_string))
67 LOG(
"%s: Detected hard reboot.\n", __func__);
68 ret = reboot_type_t::HARD;
74 LOG(
"%s: Failed to open file\n", __func__);
79 static gboolean reboot_reason_cb(gpointer data)
81 static unsigned int count = 0;
82 constexpr
unsigned int max_count = 120 / REBOOT_REASON_RETRY_INTERVAL_SECONDS;
84 reboot_type_t reboot_type = getRebootType();
85 if(reboot_type_t::UNAVAILABLE == reboot_type)
87 if(max_count >= count++)
89 return G_SOURCE_CONTINUE;
93 LOG(
"%s: Exceeded retry limit.\n", __func__);
94 return G_SOURCE_REMOVE;
99 LOG(
"%s: Got reboot reason in async check. Applying display configuration.\n", __func__);
101 ptr->sync_display_ports_with_reboot_reason(reboot_type);
102 return G_SOURCE_REMOVE;
106 static inline bool doForceDisplayOnPostReboot()
108 const char * flag_filename =
"/opt/force_display_on_after_reboot";
110 if(0 == access(flag_filename, F_OK))
112 LOG(
"%s: %s\n", __func__, (
true == ret ?
"true" :
"false"));
116 namespace pwrMgrProductTraits
120 bool ux_controller::set_bootloader_pattern(mfrBlPattern_t pattern)
123 invalidateAsyncBootloaderPattern =
true;
125 return _set_bootloader_pattern(pattern);
128 bool ux_controller::_set_bootloader_pattern(mfrBlPattern_t pattern)
const
132 if (
false == enableSilentRebootSupport)
136 mfrparam.pattern = pattern;
139 LOG(
"Warning! Call to IARM_BUS_MFRLIB_API_SetBootLoaderPattern failed.\n");
144 LOG(
"%s: successfully set pattern %d\n", __func__, (
int) pattern);
148 void ux_controller::_set_bootloader_pattern_async(mfrBlPattern_t pattern)
const
151 const unsigned int retry_interval_seconds = 5;
152 unsigned int remaining_retries = 12;
153 LOG(
"%s start for pattern 0x%x\n", __func__, pattern);
156 std::this_thread::sleep_for(std::chrono::seconds(retry_interval_seconds));
157 std::unique_lock <std::mutex> lock (mutex);
158 if(
false == invalidateAsyncBootloaderPattern)
160 ret = _set_bootloader_pattern(pattern);
164 LOG(
"%s: bootloader pattern invalidated. Aborting.\n", __func__);
168 }
while ((
false == ret) && (0 < --remaining_retries));
171 LOG(
"%s returns.\n", __func__);
174 bool ux_controller::set_bootloader_pattern_fault_tolerant(mfrBlPattern_t pattern)
179 ret = _set_bootloader_pattern(pattern);
184 invalidateAsyncBootloaderPattern =
false;
186 std::thread retry_thread(&ux_controller::_set_bootloader_pattern_async,
this, pattern);
187 retry_thread.detach();
192 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)
194 LOG(
"%s: initializing for profile id %d, name %s\n", __func__,
id, name.c_str());
195 initialize_safe_defaults();
198 void ux_controller::initialize_safe_defaults()
200 enableMultiColourLedSupport =
false;
201 enableSilentRebootSupport =
true;
202 preferedPowerModeOnReboot = POWER_MODE_LAST_KNOWN;
203 invalidateAsyncBootloaderPattern =
false;
204 firstPowerTransitionComplete =
false;
206 if (DEVICE_TYPE_STB == deviceType)
208 ledEnabledInStandby =
false;
209 ledEnabledInOnState =
true;
213 ledEnabledInStandby =
true;
214 ledEnabledInOnState =
true;
218 void ux_controller::sync_power_led_with_power_state(IARM_Bus_PWRMgr_PowerState_t power_state)
const
220 if (
true == enableMultiColourLedSupport)
222 LOG(
"Warning! Device supports multi-colour LEDs but it isn't handled.");
226 if (IARM_BUS_PWRMGR_POWERSTATE_ON == power_state)
227 led_state = ledEnabledInOnState;
229 led_state = ledEnabledInStandby;
233 LOG(
"%s: setting power LED State to %s\n", __func__, (led_state ?
"ON" :
"FALSE"));
238 LOG(
"%s: Warning! exception caught when trying to change FP state\n", __func__);
242 void ux_controller::sync_display_ports_with_power_state(IARM_Bus_PWRMgr_PowerState_t power_state)
const
244 _SetAVPortsPowerState(power_state);
246 bool ux_controller::initialize_ux_controller(
unsigned int profile_id)
251 case DEFAULT_STB_PROFILE:
255 case DEFAULT_TV_PROFILE:
259 case DEFAULT_STB_PROFILE_EUROPE:
263 case DEFAULT_TV_PROFILE_EUROPE:
268 LOG(
"Error! Unsupported product profile id %d\n", profile_id);
286 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)
288 preferedPowerModeOnReboot = POWER_MODE_LIGHT_SLEEP;
291 bool ux_controller_tv_eu::applyPowerStateChangeConfig(IARM_Bus_PWRMgr_PowerState_t new_state, IARM_Bus_PWRMgr_PowerState_t prev_state)
294 sync_display_ports_with_power_state(new_state);
295 ret = set_bootloader_pattern((IARM_BUS_PWRMGR_POWERSTATE_ON == new_state ? mfrBL_PATTERN_NORMAL : mfrBL_PATTERN_SILENT_LED_ON));
299 bool ux_controller_tv_eu::applyPreRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
const
303 bool ux_controller_tv_eu::applyPreMaintenanceRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
306 if (IARM_BUS_PWRMGR_POWERSTATE_ON != current_state)
308 ret = set_bootloader_pattern(mfrBL_PATTERN_SILENT);
313 bool ux_controller_tv_eu::applyPostRebootConfig(IARM_Bus_PWRMgr_PowerState_t target_state, IARM_Bus_PWRMgr_PowerState_t last_known_state )
319 if ((IARM_BUS_PWRMGR_POWERSTATE_ON == last_known_state) && (IARM_BUS_PWRMGR_POWERSTATE_STANDBY == target_state))
323 sync_display_ports_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_ON);
327 sync_display_ports_with_power_state(target_state);
334 mfrBlPattern_t pattern = mfrBL_PATTERN_NORMAL;
335 switch (target_state)
337 case IARM_BUS_PWRMGR_POWERSTATE_ON:
341 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY:
342 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY_LIGHT_SLEEP:
343 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP:
344 pattern = mfrBL_PATTERN_SILENT_LED_ON;
347 LOG(
"%s: Warning! Unhandled power transition. New state: %d\n", __func__, target_state);
350 ret = set_bootloader_pattern_fault_tolerant(pattern);
354 IARM_Bus_PWRMgr_PowerState_t ux_controller_tv_eu::getPreferredPostRebootPowerState(IARM_Bus_PWRMgr_PowerState_t prev_state)
const
356 return IARM_BUS_PWRMGR_POWERSTATE_STANDBY;
364 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)
366 preferedPowerModeOnReboot = POWER_MODE_LIGHT_SLEEP;
369 bool ux_controller_stb_eu::applyPowerStateChangeConfig(IARM_Bus_PWRMgr_PowerState_t new_state, IARM_Bus_PWRMgr_PowerState_t prev_state)
371 sync_display_ports_with_power_state(new_state);
372 sync_power_led_with_power_state(new_state);
376 bool ux_controller_stb_eu::applyPreRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
const
380 bool ux_controller_stb_eu::applyPreMaintenanceRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
383 if (IARM_BUS_PWRMGR_POWERSTATE_ON != current_state)
385 ret = set_bootloader_pattern(mfrBL_PATTERN_SILENT);
390 bool ux_controller_stb_eu::applyPostRebootConfig(IARM_Bus_PWRMgr_PowerState_t target_state, IARM_Bus_PWRMgr_PowerState_t last_known_state )
393 if ((IARM_BUS_PWRMGR_POWERSTATE_ON == last_known_state) && (IARM_BUS_PWRMGR_POWERSTATE_STANDBY == target_state))
396 sync_power_led_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_ON);
397 sync_display_ports_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_ON);
401 sync_power_led_with_power_state(target_state);
402 sync_display_ports_with_power_state(target_state);
406 ret = set_bootloader_pattern_fault_tolerant(mfrBL_PATTERN_NORMAL);
410 IARM_Bus_PWRMgr_PowerState_t ux_controller_stb_eu::getPreferredPostRebootPowerState(IARM_Bus_PWRMgr_PowerState_t prev_state)
const
412 return IARM_BUS_PWRMGR_POWERSTATE_STANDBY;
419 ux_controller_tv::ux_controller_tv(
unsigned int in_id,
const std::string &in_name) :
ux_controller(in_id, in_name, DEVICE_TYPE_TV)
421 preferedPowerModeOnReboot = POWER_MODE_LIGHT_SLEEP;
424 bool ux_controller_tv::applyPowerStateChangeConfig(IARM_Bus_PWRMgr_PowerState_t new_state, IARM_Bus_PWRMgr_PowerState_t prev_state)
427 if(
false == firstPowerTransitionComplete)
428 firstPowerTransitionComplete =
true;
432 sync_display_ports_with_power_state(new_state);
433 bool ret = set_bootloader_pattern((IARM_BUS_PWRMGR_POWERSTATE_ON == new_state ? mfrBL_PATTERN_NORMAL : mfrBL_PATTERN_SILENT_LED_ON));
437 bool ux_controller_tv::applyPreRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
const
441 bool ux_controller_tv::applyPreMaintenanceRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
444 if (IARM_BUS_PWRMGR_POWERSTATE_ON != current_state)
446 ret = set_bootloader_pattern(mfrBL_PATTERN_SILENT_LED_ON);
451 bool ux_controller_tv::applyPostRebootConfig(IARM_Bus_PWRMgr_PowerState_t target_state, IARM_Bus_PWRMgr_PowerState_t last_known_state )
454 sync_power_led_with_power_state(target_state);
456 if ((IARM_BUS_PWRMGR_POWERSTATE_ON == last_known_state) && (IARM_BUS_PWRMGR_POWERSTATE_STANDBY == target_state))
470 if(
true == doForceDisplayOnPostReboot() || (
true == isTVOperatingInFactory()))
471 sync_display_ports_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_ON);
474 reboot_type_t isHardReboot = getRebootType();
475 switch (isHardReboot)
477 case reboot_type_t::HARD:
478 sync_display_ports_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_STANDBY);
481 case reboot_type_t::SOFT:
482 sync_display_ports_with_power_state(IARM_BUS_PWRMGR_POWERSTATE_ON);
486 g_timeout_add_seconds(REBOOT_REASON_RETRY_INTERVAL_SECONDS, reboot_reason_cb,
this);
493 sync_display_ports_with_power_state(target_state);
500 mfrBlPattern_t pattern = mfrBL_PATTERN_NORMAL;
501 switch (target_state)
503 case IARM_BUS_PWRMGR_POWERSTATE_ON:
507 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY:
508 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY_LIGHT_SLEEP:
509 case IARM_BUS_PWRMGR_POWERSTATE_STANDBY_DEEP_SLEEP:
510 pattern = mfrBL_PATTERN_SILENT_LED_ON;
513 LOG(
"%s: Warning! Unhandled power transition. New state: %d\n", __func__, target_state);
516 ret = set_bootloader_pattern_fault_tolerant(pattern);
520 IARM_Bus_PWRMgr_PowerState_t ux_controller_tv::getPreferredPostRebootPowerState(IARM_Bus_PWRMgr_PowerState_t prev_state)
const
522 return IARM_BUS_PWRMGR_POWERSTATE_STANDBY;
525 void ux_controller_tv::sync_display_ports_with_reboot_reason(reboot_type_t reboot_type)
529 if(
false == firstPowerTransitionComplete)
532 sync_display_ports_with_power_state(reboot_type_t::HARD == reboot_type? IARM_BUS_PWRMGR_POWERSTATE_STANDBY : IARM_BUS_PWRMGR_POWERSTATE_ON);
542 ux_controller_stb::ux_controller_stb(
unsigned int in_id,
const std::string &in_name) :
ux_controller(in_id, in_name, DEVICE_TYPE_STB)
544 preferedPowerModeOnReboot = POWER_MODE_LAST_KNOWN;
545 enableSilentRebootSupport =
false;
548 bool ux_controller_stb::applyPowerStateChangeConfig(IARM_Bus_PWRMgr_PowerState_t new_state, IARM_Bus_PWRMgr_PowerState_t prev_state)
550 sync_display_ports_with_power_state(new_state);
551 sync_power_led_with_power_state(new_state);
555 bool ux_controller_stb::applyPreRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
const
559 bool ux_controller_stb::applyPreMaintenanceRebootConfig(IARM_Bus_PWRMgr_PowerState_t current_state)
565 bool ux_controller_stb::applyPostRebootConfig(IARM_Bus_PWRMgr_PowerState_t target_state, IARM_Bus_PWRMgr_PowerState_t last_known_state )
568 sync_power_led_with_power_state(target_state);
569 sync_display_ports_with_power_state(target_state);
573 IARM_Bus_PWRMgr_PowerState_t ux_controller_stb::getPreferredPostRebootPowerState(IARM_Bus_PWRMgr_PowerState_t prev_state)
const