2727#include "applib/ui/dialogs/expandable_dialog.h"
2828#include "applib/ui/option_menu_window.h"
2929#include "applib/ui/ui.h"
30+ #include "drivers/ambient_light.h"
3031#include "kernel/core_dump.h"
3132#include "kernel/event_loop.h"
3233#include "kernel/pbl_malloc.h"
3334#include "kernel/ui/modals/modal_manager.h"
35+ #include "kernel/util/sleep.h"
3436#include "mfg/mfg_info.h"
3537#include "mfg/mfg_serials.h"
3638#include "resource/resource_ids.auto.h"
3739#include "services/common/bluetooth/local_id.h"
3840#include "services/common/i18n/i18n.h"
41+ #include "services/common/light.h"
3942#include "services/common/status_led.h"
4043#include "services/common/system_task.h"
4144#include "services/normal/stationary.h"
7174enum {
7275 DebuggingItemCoreDumpNow = 0 ,
7376 DebuggingItemCoreDumpShortcut ,
77+ DebuggingItemALSThreshold ,
7478 DebuggingItem_Count ,
7579};
7680
@@ -135,6 +139,11 @@ typedef struct SettingsSystemData {
135139 Window window ;
136140 MenuLayer menu_layer ;
137141 StatusBarLayer status_layer ;
142+
143+ // ALS threshold data
144+ char als_threshold_buffer [16 ]; // Buffer for formatted ALS threshold
145+ char als_status_buffer [64 ]; // Buffer for NumberWindow label with status
146+ bool als_adjustment_active ; // Track if ALS adjustment is active
138147} SettingsSystemData ;
139148
140149typedef enum {
@@ -373,12 +382,95 @@ static void prv_maybe_trigger_core_dump() {
373382 app_confirmation_dialog_push (confirmation_dialog );
374383}
375384
385+ // ALS Threshold Settings
386+ /////////////////////////////
387+
388+ static void prv_update_als_threshold_label (NumberWindow * number_window , SettingsSystemData * data ) {
389+ uint32_t current_reading = ambient_light_get_light_level ();
390+ uint32_t current_threshold = (uint32_t )number_window_get_value (number_window );
391+ bool would_backlight_be_on = current_reading <= current_threshold ;
392+
393+ snprintf (data -> als_status_buffer , sizeof (data -> als_status_buffer ),
394+ "Backlight: %s" ,
395+ would_backlight_be_on ? "ON" : "OFF" );
396+
397+ number_window_set_label (number_window , data -> als_status_buffer );
398+ }
399+
400+ static void prv_als_threshold_incremented (NumberWindow * number_window , void * context ) {
401+ SettingsSystemData * data = (SettingsSystemData * )context ;
402+ prv_update_als_threshold_label (number_window , data );
403+ }
404+
405+ static void prv_als_threshold_decremented (NumberWindow * number_window , void * context ) {
406+ SettingsSystemData * data = (SettingsSystemData * )context ;
407+ prv_update_als_threshold_label (number_window , data );
408+ }
409+
410+ static void prv_als_threshold_selected (NumberWindow * number_window , void * context ) {
411+ SettingsSystemData * data = (SettingsSystemData * )context ;
412+ uint32_t new_threshold = (uint32_t )number_window_get_value (number_window );
413+ backlight_set_ambient_threshold (new_threshold );
414+ data -> als_adjustment_active = false;
415+ light_allow (true);
416+ app_window_stack_remove (& number_window -> window , true /* animated */ );
417+ }
418+
419+ static void prv_als_threshold_menu_push (SettingsSystemData * data ) {
420+ // Disable backlight while adjusting ALS threshold to prevent skewing readings
421+ light_allow (false);
422+ data -> als_adjustment_active = true;
423+
424+ // Give time for backlight to turn off
425+ // If we don't do this, the text may say the false result
426+ // until the user changes the value
427+ psleep (200 );
428+
429+ // Get current ambient light reading to show backlight status
430+ uint32_t current_reading = ambient_light_get_light_level ();
431+ uint32_t current_threshold = backlight_get_ambient_threshold ();
432+ bool would_backlight_be_on = current_reading <= current_threshold ;
433+
434+ // Create descriptive label with current status
435+ snprintf (data -> als_status_buffer , sizeof (data -> als_status_buffer ),
436+ "Backlight: %s" ,
437+ would_backlight_be_on ? "ON" : "OFF" );
438+
439+ NumberWindow * number_window = number_window_create (
440+ data -> als_status_buffer ,
441+ (NumberWindowCallbacks ) {
442+ .selected = prv_als_threshold_selected ,
443+ .incremented = prv_als_threshold_incremented ,
444+ .decremented = prv_als_threshold_decremented ,
445+ },
446+ data
447+ );
448+
449+ if (!number_window ) {
450+ // Re-enable backlight if NumberWindow creation failed
451+ data -> als_adjustment_active = false;
452+ light_allow (true);
453+ return ;
454+ }
455+
456+
457+ // Set reasonable min/max values for ALS threshold
458+ number_window_set_min (number_window , 0 );
459+ number_window_set_max (number_window , AMBIENT_LIGHT_LEVEL_MAX );
460+ number_window_set_step_size (number_window , 1 );
461+ number_window_set_value (number_window , (int32_t )current_threshold );
462+
463+ const bool animated = true;
464+ app_window_stack_push (& number_window -> window , animated );
465+ }
466+
376467// Debug options window
377468///////////////////////
378469
379470static const char * s_debugging_titles [DebuggingItem_Count ] = {
380471 [DebuggingItemCoreDumpNow ] = i18n_noop ("Bug report now" ),
381472 [DebuggingItemCoreDumpShortcut ] = i18n_noop ("Bug shortcut" ),
473+ [DebuggingItemALSThreshold ] = i18n_noop ("ALS Threshold" ),
382474};
383475
384476static void prv_debugging_draw_row_callback (GContext * ctx , const Layer * cell_layer ,
@@ -388,10 +480,22 @@ static void prv_debugging_draw_row_callback(GContext* ctx, const Layer *cell_lay
388480
389481 SettingsSystemData * data = (SettingsSystemData * ) context ;
390482
483+ // Check if user canceled out of ALS adjustment (this gets called when we return to settings menu)
484+ if (data -> als_adjustment_active ) {
485+ data -> als_adjustment_active = false;
486+ light_allow (true);
487+ }
488+
391489 const char * title = i18n_get (s_debugging_titles [cell_index -> row ], data );
392490 const char * subtitle_text = NULL ;
393491 if (cell_index -> row == DebuggingItemCoreDumpShortcut ) {
394492 subtitle_text = shell_prefs_can_coredump_on_request () ? i18n_get ("10 back-button presses" , data ) : i18n_get ("Disabled" , data );
493+ } else if (cell_index -> row == DebuggingItemALSThreshold ) {
494+ // Show current threshold value
495+ uint32_t current_threshold = backlight_get_ambient_threshold ();
496+ snprintf (data -> als_threshold_buffer , sizeof (data -> als_threshold_buffer ),
497+ "%" PRIu32 , current_threshold );
498+ subtitle_text = data -> als_threshold_buffer ;
395499 }
396500 menu_cell_basic_draw (ctx , cell_layer , title , subtitle_text , NULL );
397501}
@@ -412,13 +516,18 @@ static uint16_t prv_debugging_get_num_rows_callback(MenuLayer *menu_layer,
412516static void prv_debugging_select_callback (MenuLayer * menu_layer ,
413517 MenuIndex * cell_index ,
414518 void * context ) {
519+ SettingsSystemData * data = (SettingsSystemData * ) context ;
520+
415521 switch (cell_index -> row ) {
416522 case DebuggingItemCoreDumpNow :
417523 prv_maybe_trigger_core_dump ();
418524 break ;
419525 case DebuggingItemCoreDumpShortcut :
420526 shell_prefs_set_coredump_on_request (!shell_prefs_can_coredump_on_request ());
421527 break ;
528+ case DebuggingItemALSThreshold :
529+ prv_als_threshold_menu_push (data );
530+ break ;
422531 default :
423532 WTF ;
424533 }
0 commit comments