mirror of
https://github.com/google/pebble.git
synced 2025-03-28 05:47:46 +00:00
303 lines
10 KiB
C
303 lines
10 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.
|
|
*/
|
|
|
|
#include "weather_data_shared.h"
|
|
|
|
#include "clar_asserts.h"
|
|
|
|
#include "drivers/rtc.h"
|
|
#include "kernel/pbl_malloc.h"
|
|
#include "services/normal/blob_db/watch_app_prefs_db.h"
|
|
#include "services/normal/blob_db/weather_db.h"
|
|
#include "services/normal/weather/weather_service_private.h"
|
|
|
|
#define WEATHER_PREFS_DATA_SIZE (sizeof(SerializedWeatherAppPrefs) + \
|
|
(sizeof(Uuid) * WEATHER_DATA_SHARED_WEATHER_DB_NUM_DB_ENTRIES))
|
|
static uint8_t s_weather_app_prefs[WEATHER_PREFS_DATA_SIZE];
|
|
|
|
static const WeatherDBKey s_keys[] = {
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
|
|
},
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2
|
|
},
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3
|
|
},
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4
|
|
},
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5
|
|
},
|
|
};
|
|
|
|
static WeatherDBEntry *s_entries[WEATHER_DATA_SHARED_WEATHER_DB_NUM_DB_ENTRIES];
|
|
static size_t s_entry_sizes[WEATHER_DATA_SHARED_WEATHER_DB_NUM_DB_ENTRIES];
|
|
|
|
static char *s_entry_names[] = {
|
|
TEST_WEATHER_DB_LOCATION_PALO_ALTO,
|
|
TEST_WEATHER_DB_LOCATION_KITCHENER,
|
|
TEST_WEATHER_DB_LOCATION_WATERLOO,
|
|
TEST_WEATHER_DB_LOCATION_RWC,
|
|
TEST_WEATHER_DB_LOCATION_SF,
|
|
};
|
|
|
|
static char *s_entry_phrases[] = {
|
|
TEST_WEATHER_DB_SHORT_PHRASE_SUNNY,
|
|
TEST_WEATHER_DB_SHORT_PHRASE_PARTLY_CLOUDY,
|
|
TEST_WEATHER_DB_SHORT_PHRASE_HEAVY_SNOW,
|
|
TEST_WEATHER_DB_SHORT_PHRASE_HEAVY_RAIN,
|
|
TEST_WEATHER_DB_SHORT_PHRASE_PARTLY_CLOUDY,
|
|
};
|
|
|
|
static const WeatherDBEntry s_entry_bases[] = {
|
|
{
|
|
.version = WEATHER_DB_CURRENT_VERSION,
|
|
.is_current_location = true,
|
|
.current_temp = 68,
|
|
.current_weather_type = WeatherType_Sun,
|
|
.today_high_temp = 68,
|
|
.today_low_temp = 52,
|
|
.tomorrow_weather_type = WeatherType_CloudyDay,
|
|
.tomorrow_high_temp = 70,
|
|
.tomorrow_low_temp = 60,
|
|
},
|
|
{
|
|
.version = WEATHER_DB_CURRENT_VERSION,
|
|
.is_current_location = false,
|
|
.current_temp = -10,
|
|
.current_weather_type = WeatherType_PartlyCloudy,
|
|
.today_high_temp = 0,
|
|
.today_low_temp = -11,
|
|
.tomorrow_weather_type = WeatherType_CloudyDay,
|
|
.tomorrow_high_temp = 2,
|
|
.tomorrow_low_temp = -3,
|
|
},
|
|
{
|
|
.version = WEATHER_DB_CURRENT_VERSION,
|
|
.is_current_location = false,
|
|
.current_temp = -99,
|
|
.current_weather_type = WeatherType_HeavySnow,
|
|
.today_high_temp = -98,
|
|
.today_low_temp = -99,
|
|
.tomorrow_weather_type = WeatherType_Sun,
|
|
.tomorrow_high_temp = 2,
|
|
.tomorrow_low_temp = 1,
|
|
},
|
|
{
|
|
.version = WEATHER_DB_CURRENT_VERSION,
|
|
.is_current_location = true,
|
|
.current_temp = 60,
|
|
.current_weather_type = WeatherType_HeavyRain,
|
|
.today_high_temp = 70,
|
|
.today_low_temp = 50,
|
|
.tomorrow_weather_type = WeatherType_PartlyCloudy,
|
|
.tomorrow_high_temp = 70,
|
|
.tomorrow_low_temp = 60,
|
|
},
|
|
{
|
|
.version = WEATHER_DB_CURRENT_VERSION,
|
|
.is_current_location = true,
|
|
.current_temp = 60,
|
|
.current_weather_type = WeatherType_PartlyCloudy,
|
|
.today_high_temp = 70,
|
|
.today_low_temp = 50,
|
|
.tomorrow_weather_type = WeatherType_PartlyCloudy,
|
|
.tomorrow_high_temp = 70,
|
|
.tomorrow_low_temp = 60,
|
|
}
|
|
};
|
|
|
|
// Fake out watch_app_prefs calls
|
|
void watch_app_prefs_destroy_weather(SerializedWeatherAppPrefs *prefs) {}
|
|
|
|
SerializedWeatherAppPrefs *watch_app_prefs_get_weather(void) {
|
|
SerializedWeatherAppPrefs *prefs = (SerializedWeatherAppPrefs *) s_weather_app_prefs;
|
|
prefs->num_locations = WEATHER_DATA_SHARED_WEATHER_DB_NUM_DB_ENTRIES;
|
|
for (int idx = 0; idx < WEATHER_DATA_SHARED_WEATHER_DB_NUM_DB_ENTRIES; idx++) {
|
|
prefs->locations[idx] = s_keys[idx];
|
|
}
|
|
return prefs;
|
|
}
|
|
|
|
static WeatherDBEntry *prv_create_entry(const WeatherDBEntry *base_entry, char *location,
|
|
char *phrase, size_t *size_out) {
|
|
PascalString16List pstring16_list;
|
|
PascalString16 *location_name;
|
|
PascalString16 *short_phrase;
|
|
size_t data_size;
|
|
|
|
location_name = pstring_create_pstring16_from_string(location);
|
|
short_phrase = pstring_create_pstring16_from_string(phrase);
|
|
|
|
data_size = strlen(location) +
|
|
strlen(phrase) +
|
|
sizeof(uint16_t) * 2; // One for each string
|
|
|
|
const size_t entry_size = sizeof(WeatherDBEntry) + data_size;
|
|
WeatherDBEntry *entry = task_zalloc_check(entry_size);
|
|
*entry = *base_entry;
|
|
entry->pstring16s.data_size = data_size;
|
|
entry->last_update_time_utc = rtc_get_time();
|
|
|
|
pstring_project_list_on_serialized_array(&pstring16_list, &entry->pstring16s);
|
|
pstring_add_pstring16_to_list(&pstring16_list, location_name);
|
|
pstring_add_pstring16_to_list(&pstring16_list, short_phrase);
|
|
|
|
pstring_destroy_pstring16(location_name);
|
|
pstring_destroy_pstring16(short_phrase);
|
|
|
|
*size_out = entry_size;
|
|
return entry;
|
|
}
|
|
|
|
static void prv_initialize_entries(void) {
|
|
for (int idx = 0; idx < WEATHER_DATA_SHARED_WEATHER_DB_NUM_DB_ENTRIES; idx++) {
|
|
WeatherDBEntry *entry = prv_create_entry(&s_entry_bases[idx],
|
|
s_entry_names[idx],
|
|
s_entry_phrases[idx],
|
|
&s_entry_sizes[idx]);
|
|
|
|
// Make the last entry contain a timestamp that is too old to be included in weather_service
|
|
// forecast list
|
|
if (idx == WEATHER_DATA_SHARED_NUM_VALID_TIMESTAMP_ENTRIES) {
|
|
entry->last_update_time_utc = (time_start_of_today() - SECONDS_PER_DAY - 1);
|
|
}
|
|
cl_assert_equal_i(S_SUCCESS, weather_db_insert((uint8_t*)&s_keys[idx],
|
|
sizeof(WeatherDBKey),
|
|
(uint8_t*)entry,
|
|
s_entry_sizes[idx]));
|
|
s_entries[idx] = entry;
|
|
}
|
|
}
|
|
|
|
void weather_shared_data_init(void) {
|
|
rtc_set_time(1461765790); // 2016-04-27T14:03:10+00:00
|
|
prv_initialize_entries();
|
|
}
|
|
|
|
void weather_shared_data_cleanup(void) {
|
|
for (int i = 0; i < WEATHER_DATA_SHARED_WEATHER_DB_NUM_DB_ENTRIES; i++) {
|
|
if (s_entries[i]) {
|
|
task_free(s_entries[i]);
|
|
s_entries[i] = NULL;
|
|
}
|
|
}
|
|
|
|
// Flush DB
|
|
cl_assert_equal_i(S_SUCCESS, weather_db_flush());
|
|
}
|
|
|
|
|
|
const WeatherDBKey *weather_shared_data_get_key(int index) {
|
|
return &s_keys[index];
|
|
}
|
|
|
|
WeatherDBEntry *weather_shared_data_get_entry(int index) {
|
|
return s_entries[index];
|
|
}
|
|
|
|
size_t weather_shared_data_get_entry_size(int index) {
|
|
return s_entry_sizes[index];
|
|
}
|
|
|
|
char *weather_shared_data_get_entry_name(int index) {
|
|
return s_entry_names[index];
|
|
}
|
|
|
|
char *weather_shared_data_get_entry_phrase(int index) {
|
|
return s_entry_phrases[index];
|
|
}
|
|
|
|
int weather_shared_data_get_index_of_key(const WeatherDBKey *key) {
|
|
for (int idx = 0; idx < WEATHER_DATA_SHARED_WEATHER_DB_NUM_DB_ENTRIES; idx++) {
|
|
if (uuid_equal(key, &s_keys[idx])) {
|
|
return idx;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void weather_shared_data_assert_entries_equal(const WeatherDBKey *key, WeatherDBEntry *to_check,
|
|
WeatherDBEntry *original) {
|
|
cl_assert_equal_i(to_check->version, original->version);
|
|
cl_assert_equal_b(to_check->is_current_location, original->is_current_location);
|
|
cl_assert_equal_i(to_check->current_temp, original->current_temp);
|
|
cl_assert_equal_i(to_check->current_weather_type, original->current_weather_type);
|
|
cl_assert_equal_i(to_check->today_high_temp, original->today_high_temp);
|
|
cl_assert_equal_i(to_check->today_low_temp, original->today_low_temp);
|
|
cl_assert_equal_i(to_check->tomorrow_weather_type, original->tomorrow_weather_type);
|
|
cl_assert_equal_i(to_check->tomorrow_high_temp, original->tomorrow_high_temp);
|
|
cl_assert_equal_i(to_check->tomorrow_low_temp, original->tomorrow_low_temp);
|
|
cl_assert_equal_i(to_check->last_update_time_utc, original->last_update_time_utc);
|
|
|
|
PascalString16List pstring16_list;
|
|
pstring_project_list_on_serialized_array(&pstring16_list, &to_check->pstring16s);
|
|
cl_assert_equal_i(pstring16_list.count, 2);
|
|
|
|
PascalString16 *pstring;
|
|
|
|
pstring = pstring_get_pstring16_from_list(&pstring16_list, 0);
|
|
|
|
int index = weather_shared_data_get_index_of_key(key);
|
|
if (index == -1) {
|
|
cl_fail("key not found!");
|
|
}
|
|
|
|
cl_assert_equal_i(pstring->str_length, strlen(s_entry_names[index]));
|
|
char loc[WEATHER_SERVICE_MAX_WEATHER_LOCATION_BUFFER_SIZE];
|
|
pstring_pstring16_to_string(pstring, loc);
|
|
cl_assert_equal_s(loc, s_entry_names[index]);
|
|
|
|
pstring = pstring_get_pstring16_from_list(&pstring16_list, 1);
|
|
cl_assert_equal_i(pstring->str_length, strlen(s_entry_phrases[index]));
|
|
char phrase[WEATHER_SERVICE_MAX_SHORT_PHRASE_BUFFER_SIZE];
|
|
pstring_pstring16_to_string(pstring, phrase);
|
|
cl_assert_equal_s(phrase, s_entry_phrases[index]);
|
|
}
|
|
|
|
bool weather_shared_data_get_key_exists(WeatherDBKey *key) {
|
|
return weather_shared_data_get_index_of_key(key) != -1;
|
|
}
|
|
|
|
status_t weather_db_insert_stale(const uint8_t *key, int key_len, const uint8_t *val, int val_len);
|
|
|
|
size_t weather_shared_data_insert_stale_entry(WeatherDBKey *key) {
|
|
const WeatherDBEntry stale_entry = {
|
|
.version = WEATHER_DB_CURRENT_VERSION - 1,
|
|
.is_current_location = true,
|
|
.current_temp = 68,
|
|
.current_weather_type = WeatherType_Sun,
|
|
.today_high_temp = 68,
|
|
.today_low_temp = 52,
|
|
.tomorrow_weather_type = WeatherType_CloudyDay,
|
|
.tomorrow_high_temp = 70,
|
|
.tomorrow_low_temp = 60,
|
|
};
|
|
|
|
WeatherDBEntry *entry = prv_create_entry(&stale_entry,
|
|
s_entry_names[0],
|
|
s_entry_phrases[0],
|
|
&s_entry_sizes[0]);
|
|
|
|
cl_assert_equal_i(S_SUCCESS, weather_db_insert_stale((uint8_t*)key,
|
|
sizeof(WeatherDBKey),
|
|
(uint8_t*)entry,
|
|
s_entry_sizes[0]));
|
|
return s_entry_sizes[0];
|
|
}
|