mirror of
https://github.com/google/pebble.git
synced 2025-11-22 23:40:54 -05:00
128 lines
5.0 KiB
C
128 lines
5.0 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#if PLATFORM_SPALDING
|
|
|
|
#include "display_calibration_prompt.h"
|
|
|
|
#include "applib/ui/dialogs/confirmation_dialog.h"
|
|
#include "apps/system_apps/settings/settings_display_calibration.h"
|
|
#include "kernel/event_loop.h"
|
|
#include "kernel/ui/modals/modal_manager.h"
|
|
#include "mfg/mfg_info.h"
|
|
#include "mfg/mfg_serials.h"
|
|
#include "resource/resource_ids.auto.h"
|
|
#include "services/common/i18n/i18n.h"
|
|
#include "services/common/new_timer/new_timer.h"
|
|
#include "shell/prefs.h"
|
|
#include "util/size.h"
|
|
|
|
// The calibration screen will be changing the screen offsets, so it's best that it remains on top
|
|
// of most other modals (generic, alerts, etc) to prevent confusion about the screen's alignment.
|
|
static const ModalPriority MODAL_PRIORITY = ModalPriorityCritical;
|
|
|
|
static void prv_calibrate_confirm_pop(ClickRecognizerRef recognizer, void *context) {
|
|
i18n_free_all(context);
|
|
confirmation_dialog_pop((ConfirmationDialog *)context);
|
|
}
|
|
|
|
static void prv_calibrate_confirm_cb(ClickRecognizerRef recognizer, void *context) {
|
|
settings_display_calibration_push(modal_manager_get_window_stack(MODAL_PRIORITY));
|
|
prv_calibrate_confirm_pop(recognizer, context);
|
|
}
|
|
|
|
static void prv_calibrate_click_config(void *context) {
|
|
window_single_click_subscribe(BUTTON_ID_UP, prv_calibrate_confirm_cb);
|
|
window_single_click_subscribe(BUTTON_ID_DOWN, prv_calibrate_confirm_pop);
|
|
window_single_click_subscribe(BUTTON_ID_BACK, prv_calibrate_confirm_pop);
|
|
}
|
|
|
|
static TimerID s_timer = TIMER_INVALID_ID;
|
|
|
|
static void prv_push_calibration_dialog(void *data) {
|
|
shell_prefs_set_should_prompt_display_calibration(false);
|
|
|
|
ConfirmationDialog *confirmation_dialog = confirmation_dialog_create("Calibrate Prompt");
|
|
Dialog *dialog = confirmation_dialog_get_dialog(confirmation_dialog);
|
|
|
|
dialog_set_text(dialog, i18n_get("Your screen may need calibration. Calibrate it now?",
|
|
confirmation_dialog));
|
|
dialog_set_background_color(dialog, GColorMediumAquamarine);
|
|
dialog_set_icon(dialog, RESOURCE_ID_GENERIC_PIN_TINY);
|
|
confirmation_dialog_set_click_config_provider(confirmation_dialog,
|
|
prv_calibrate_click_config);
|
|
confirmation_dialog_push(confirmation_dialog,
|
|
modal_manager_get_window_stack(MODAL_PRIORITY));
|
|
}
|
|
|
|
static bool prv_display_has_user_offset(void) {
|
|
GPoint display_offset = shell_prefs_get_display_offset();
|
|
GPoint mfg_display_offset = mfg_info_get_disp_offsets();
|
|
return (!gpoint_equal(&display_offset, &mfg_display_offset));
|
|
}
|
|
|
|
static void prv_timer_callback(void *data) {
|
|
new_timer_delete(s_timer);
|
|
s_timer = TIMER_INVALID_ID;
|
|
|
|
// last check: make sure we need to display the prompt in case something changed in the
|
|
// time that the timer was waiting.
|
|
if (!shell_prefs_should_prompt_display_calibration()) {
|
|
return;
|
|
}
|
|
|
|
launcher_task_add_callback(prv_push_calibration_dialog, NULL);
|
|
}
|
|
|
|
T_STATIC bool prv_is_known_misaligned_serial_number(const char *serial) {
|
|
// Filter watches known to be misaligned based on the serial number. This is possible because
|
|
// Serial numbers are represented as strings as described in:
|
|
// https://pebbletechnology.atlassian.net/wiki/display/DEV/Hardware+Serial+Numbering
|
|
// All watches of the same model produced from the same manufacturer on the same date, on the
|
|
// same manufacturing line, will share the same first 8 characters of the serial number. In this
|
|
// way, batches which are misaligned can be identified by a string comparison on these characters.
|
|
//
|
|
// NOTE: This also conveniently excludes test automation boards, so the dialog should not
|
|
// appear during integration tests.
|
|
const char *ranges[] = { "Q402445E" };
|
|
for (size_t i = 0; i < ARRAY_LENGTH(ranges); i++) {
|
|
if (strncmp(serial, ranges[i], strlen(ranges[i])) == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool prv_is_potentially_misaligned_watch() {
|
|
return !prv_display_has_user_offset() &&
|
|
prv_is_known_misaligned_serial_number(mfg_get_serial_number());
|
|
}
|
|
|
|
void display_calibration_prompt_show_if_needed(void) {
|
|
if (!prv_is_potentially_misaligned_watch()) {
|
|
shell_prefs_set_should_prompt_display_calibration(false);
|
|
return;
|
|
}
|
|
|
|
if (shell_prefs_should_prompt_display_calibration()) {
|
|
s_timer = new_timer_create();
|
|
const uint32_t prompt_delay_time_ms = MS_PER_SECOND * SECONDS_PER_MINUTE;
|
|
new_timer_start(s_timer, prompt_delay_time_ms, prv_timer_callback, NULL, 0 /* flags */);
|
|
}
|
|
}
|
|
|
|
#endif
|