mirror of
https://github.com/google/pebble
synced 2026-10-17 00:34:11 +02:00
Import of the watch repository from Pebble
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 "vibe_client.h"
|
||||
|
||||
#include "applib/ui/vibes.h"
|
||||
#include "services/normal/notifications/alerts_preferences_private.h"
|
||||
#include "services/normal/vibes/vibe_score.h"
|
||||
#include "services/normal/vibes/vibe_score_info.h"
|
||||
#include "system/logging.h"
|
||||
|
||||
static VibeScoreId prv_get_resource_for_client(VibeClient client) {
|
||||
if (client == VibeClient_AlarmsLPM) {
|
||||
return VibeScoreId_AlarmsLPM;
|
||||
}
|
||||
return alerts_preferences_get_vibe_score_for_client(client);
|
||||
}
|
||||
|
||||
VibeScore *vibe_client_get_score(VibeClient client) {
|
||||
VibeScoreId id = prv_get_resource_for_client(client);
|
||||
if (id == VibeScoreId_Disabled) {
|
||||
return NULL;
|
||||
}
|
||||
VibeScore *score = vibe_score_create_with_resource(vibe_score_info_get_resource_id(id));
|
||||
if (!score) {
|
||||
PBL_LOG(LOG_LEVEL_ERROR, "Got a null VibeScore resource!");
|
||||
}
|
||||
return score;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vibe_score.h"
|
||||
|
||||
typedef enum VibeClient {
|
||||
VibeClient_Notifications = 0,
|
||||
VibeClient_PhoneCalls,
|
||||
VibeClient_Alarms,
|
||||
VibeClient_AlarmsLPM
|
||||
} VibeClient;
|
||||
|
||||
// Returns the appropriate vibe score for the client.
|
||||
// This is determined from alert preferences.
|
||||
VibeScore *vibe_client_get_score(VibeClient client);
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 "vibe_intensity.h"
|
||||
|
||||
#include "services/common/i18n/i18n.h"
|
||||
#include "services/common/vibe_pattern.h"
|
||||
#include "services/normal/notifications/alerts_preferences_private.h"
|
||||
|
||||
uint8_t get_strength_for_intensity(VibeIntensity intensity) {
|
||||
switch (intensity) {
|
||||
case VibeIntensityLow:
|
||||
return 40;
|
||||
case VibeIntensityMedium:
|
||||
return 60;
|
||||
case VibeIntensityHigh:
|
||||
return 100;
|
||||
default:
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
||||
void vibe_intensity_init(void) {
|
||||
vibe_intensity_set(vibe_intensity_get());
|
||||
}
|
||||
|
||||
void vibe_intensity_set(VibeIntensity intensity) {
|
||||
vibes_set_default_vibe_strength(get_strength_for_intensity(intensity));
|
||||
}
|
||||
|
||||
VibeIntensity vibe_intensity_get(void) {
|
||||
return alerts_preferences_get_vibe_intensity();
|
||||
}
|
||||
|
||||
const char *vibe_intensity_get_string_for_intensity(VibeIntensity intensity) {
|
||||
switch (intensity) {
|
||||
case VibeIntensityLow: {
|
||||
/// Standard vibration pattern option that has a low intensity
|
||||
return i18n_noop("Standard - Low");
|
||||
}
|
||||
case VibeIntensityMedium: {
|
||||
/// Standard vibration pattern option that has a medium intensity
|
||||
return i18n_noop("Standard - Medium");
|
||||
}
|
||||
case VibeIntensityHigh: {
|
||||
/// Standard vibration pattern option that has a high intensity
|
||||
return i18n_noop("Standard - High");
|
||||
}
|
||||
default: {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VibeIntensity vibe_intensity_cycle_next(VibeIntensity intensity) {
|
||||
return (intensity + 1) % VibeIntensityNum;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum VibeIntensity {
|
||||
VibeIntensityLow,
|
||||
VibeIntensityMedium,
|
||||
VibeIntensityHigh,
|
||||
VibeIntensityNum,
|
||||
} VibeIntensity;
|
||||
|
||||
#if PLATFORM_SPALDING
|
||||
#define DEFAULT_VIBE_INTENSITY VibeIntensityMedium
|
||||
#else
|
||||
#define DEFAULT_VIBE_INTENSITY VibeIntensityHigh
|
||||
#endif
|
||||
|
||||
void vibe_intensity_init(void);
|
||||
|
||||
//! Returns the corresponding strength for the given level of intensity.
|
||||
//! The strength corresponds to a percentage of the max strength, ie in the range [0,100].
|
||||
uint8_t get_strength_for_intensity(VibeIntensity intensity);
|
||||
|
||||
//! Sets the intensity of ALL vibrations (not just notifications)
|
||||
void vibe_intensity_set(VibeIntensity intensity);
|
||||
|
||||
//! Gets the current vibe intensity
|
||||
VibeIntensity vibe_intensity_get(void);
|
||||
|
||||
//! Returns a string representation of the provided vibe intensity.
|
||||
//! @param intensity The intensity for which to get a string representation
|
||||
//! @return A string representation of the provided intensity, or NULL if the intensity is invalid
|
||||
const char *vibe_intensity_get_string_for_intensity(VibeIntensity intensity);
|
||||
|
||||
//! Gets the next intensity in the vibe intensity cycle
|
||||
//! @param intensity Input intensity for which to get the next intensity
|
||||
//! @return The next vibe intensity in the cycle
|
||||
VibeIntensity vibe_intensity_cycle_next(VibeIntensity intensity);
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* 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 "vibe_score.h"
|
||||
|
||||
#include "process_management/app_manager.h"
|
||||
#include "syscall/syscall.h"
|
||||
|
||||
#include "system/passert.h"
|
||||
#include "drivers/vibe.h"
|
||||
#include "applib/applib_malloc.auto.h"
|
||||
#include "util/net.h"
|
||||
|
||||
#define VIBE_SCORE_MAX_REPEAT_DELAY_MS (10000) // matches MAX_VIBE_DURATION_MS in vibe_pattern
|
||||
|
||||
static VibeNote *prv_vibe_score_get_note_list(GenericAttribute *notes_attribute) {
|
||||
return (VibeNote *)notes_attribute->data;
|
||||
}
|
||||
|
||||
static VibeNoteIndex *prv_vibe_score_get_pattern_list(GenericAttribute *pattern_attribute) {
|
||||
return (VibeNoteIndex *)pattern_attribute->data;
|
||||
}
|
||||
|
||||
static unsigned int prv_vibe_score_get_num_note_types(GenericAttribute *notes_attribute) {
|
||||
return notes_attribute->length / sizeof(VibeNote);
|
||||
}
|
||||
|
||||
static unsigned int prv_vibe_score_get_pattern_length(GenericAttribute *pattern_attribute) {
|
||||
return pattern_attribute->length / sizeof(VibeNoteIndex);
|
||||
}
|
||||
|
||||
static bool prv_vibe_score_resource_is_valid(ResAppNum app_num, uint32_t resource_id,
|
||||
uint32_t expected_signature, uint32_t *data_size) {
|
||||
// Load file signature, and check that it matches the expected_signature
|
||||
uint32_t data_signature;
|
||||
if (!(sys_resource_load_range(app_num, resource_id, 0, (uint8_t*)&data_signature,
|
||||
sizeof(data_signature)) == sizeof(data_signature) &&
|
||||
(ntohl(data_signature) == expected_signature))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Data is the second entry after the resource signature
|
||||
if (data_size) {
|
||||
size_t output_data_size = sys_resource_size(app_num, resource_id) - VIBE_DATA_OFFSET;
|
||||
*data_size = output_data_size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vibe_score_validate(VibeScore *score, uint32_t data_size) {
|
||||
if (!score) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t total_size = sizeof(VibeScore);
|
||||
|
||||
// check large enough to contain non-flexible parts
|
||||
if (data_size < total_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check version number
|
||||
if (score->version > VIBE_SCORE_VERSION) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if attr_list_size is correct
|
||||
if (score->attr_list_size != (data_size - (sizeof(VibeScore) - sizeof(GenericAttributeList)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check exact file size to contain all flexible-sized data
|
||||
for (unsigned int i = 0; i < score->attr_list.num_attributes; i++) {
|
||||
GenericAttribute * attribute = (GenericAttribute *)((uint8_t *)score + total_size);
|
||||
total_size += sizeof(GenericAttribute);
|
||||
if (data_size < total_size) {
|
||||
return false;
|
||||
}
|
||||
total_size += attribute->length;
|
||||
if (data_size < total_size) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (data_size != total_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check to see all indices point to valid notes
|
||||
GenericAttribute *notes_attribute = generic_attribute_find_attribute(&score->attr_list,
|
||||
VibeAttributeId_Notes,
|
||||
score->attr_list_size);
|
||||
GenericAttribute *pattern_attribute = generic_attribute_find_attribute(&score->attr_list,
|
||||
VibeAttributeId_Pattern,
|
||||
score->attr_list_size);
|
||||
if (!notes_attribute || !pattern_attribute) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int num_note_types = prv_vibe_score_get_num_note_types(notes_attribute);
|
||||
if (notes_attribute->length != num_note_types * sizeof(VibeNote)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VibeNoteIndex *pattern_list = prv_vibe_score_get_pattern_list(pattern_attribute);
|
||||
for (unsigned int i = 0; i < prv_vibe_score_get_pattern_length(pattern_attribute); i++) {
|
||||
if (pattern_list[i] >= num_note_types) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GenericAttribute *repeat_delay_attribute =
|
||||
generic_attribute_find_attribute(&score->attr_list, VibeAttributeId_RepeatDelay,
|
||||
score->attr_list_size);
|
||||
if (repeat_delay_attribute) {
|
||||
if (repeat_delay_attribute->length != sizeof(uint16_t)) {
|
||||
return false;
|
||||
}
|
||||
uint16_t *delay = (uint16_t *)repeat_delay_attribute->data;
|
||||
if (*delay > VIBE_SCORE_MAX_REPEAT_DELAY_MS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
VibeScore *vibe_score_create_with_resource_system(ResAppNum app_num,
|
||||
uint32_t resource_id) {
|
||||
uint32_t data_size;
|
||||
if (!prv_vibe_score_resource_is_valid(app_num, resource_id, VIBE_SIGNATURE, &data_size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VibeScore *vibe_score = applib_zalloc(data_size);
|
||||
if (!vibe_score || sys_resource_load_range(app_num, resource_id, VIBE_DATA_OFFSET,
|
||||
(uint8_t*)vibe_score, data_size) != data_size) {
|
||||
applib_free(vibe_score);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Validate the loaded command sequence
|
||||
if (!vibe_score_validate(vibe_score, data_size)) {
|
||||
applib_free(vibe_score);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vibe_score;
|
||||
}
|
||||
|
||||
unsigned int vibe_score_get_duration_ms(VibeScore *score) {
|
||||
if (!score) {
|
||||
return 0;
|
||||
}
|
||||
GenericAttribute *notes_attribute = generic_attribute_find_attribute(&score->attr_list,
|
||||
VibeAttributeId_Notes,
|
||||
score->attr_list_size);
|
||||
GenericAttribute *pattern_attribute = generic_attribute_find_attribute(&score->attr_list,
|
||||
VibeAttributeId_Pattern,
|
||||
score->attr_list_size);
|
||||
PBL_ASSERTN(notes_attribute && pattern_attribute);
|
||||
|
||||
unsigned int duration_ms = 0;
|
||||
VibeNote *note_list = prv_vibe_score_get_note_list(notes_attribute);
|
||||
VibeNoteIndex *pattern_list = prv_vibe_score_get_pattern_list(pattern_attribute);
|
||||
unsigned int pattern_length = prv_vibe_score_get_pattern_length(pattern_attribute);
|
||||
|
||||
for (unsigned int i = 0; i < pattern_length; i++) {
|
||||
VibeNote *note = ¬e_list[pattern_list[i]];
|
||||
duration_ms += (note->vibe_duration_ms + note->brake_duration_ms);
|
||||
}
|
||||
return duration_ms;
|
||||
}
|
||||
|
||||
unsigned int vibe_score_get_repeat_delay_ms(VibeScore *score) {
|
||||
if (!score) {
|
||||
return 0;
|
||||
}
|
||||
GenericAttribute *repeat_delay_attribute =
|
||||
generic_attribute_find_attribute(&score->attr_list, VibeAttributeId_RepeatDelay,
|
||||
score->attr_list_size);
|
||||
if (repeat_delay_attribute) {
|
||||
uint16_t *repeat_delay = (uint16_t *) repeat_delay_attribute->data;
|
||||
return *repeat_delay;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vibe_score_do_vibe(VibeScore *score) {
|
||||
PBL_ASSERTN(score);
|
||||
GenericAttribute *notes_attribute = generic_attribute_find_attribute(&score->attr_list,
|
||||
VibeAttributeId_Notes,
|
||||
score->attr_list_size);
|
||||
GenericAttribute *pattern_attribute = generic_attribute_find_attribute(&score->attr_list,
|
||||
VibeAttributeId_Pattern,
|
||||
score->attr_list_size);
|
||||
PBL_ASSERTN(notes_attribute && pattern_attribute);
|
||||
|
||||
VibeNote *note_list = prv_vibe_score_get_note_list(notes_attribute);
|
||||
VibeNoteIndex *pattern_list = prv_vibe_score_get_pattern_list(pattern_attribute);
|
||||
unsigned int pattern_length = prv_vibe_score_get_pattern_length(pattern_attribute);
|
||||
|
||||
for (unsigned int i = 0; i < pattern_length; i++) {
|
||||
VibeNote *note = ¬e_list[pattern_list[i]];
|
||||
if (note->vibe_duration_ms > 0) {
|
||||
sys_vibe_pattern_enqueue_step_raw(note->vibe_duration_ms, note->strength);
|
||||
}
|
||||
if (note->brake_duration_ms > 0) {
|
||||
sys_vibe_pattern_enqueue_step_raw(note->brake_duration_ms, vibe_get_braking_strength());
|
||||
}
|
||||
}
|
||||
sys_vibe_pattern_trigger_start();
|
||||
}
|
||||
|
||||
VibeScore *vibe_score_create_with_resource(uint32_t resource_id) {
|
||||
ResAppNum app_num = sys_get_current_resource_num();
|
||||
return vibe_score_create_with_resource_system(app_num, resource_id);
|
||||
}
|
||||
|
||||
void vibe_score_destroy(VibeScore *score) {
|
||||
if (!score) {
|
||||
return;
|
||||
}
|
||||
|
||||
applib_free(score);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "resource/resource.h"
|
||||
#include "util/attributes.h"
|
||||
#include "util/generic_attribute.h"
|
||||
#include "util/pack.h"
|
||||
|
||||
#define VIBE_SCORE_VERSION (1)
|
||||
#define VIBE_SIGNATURE MAKE_WORD('V', 'I', 'B', 'E')
|
||||
#define VIBE_DATA_OFFSET sizeof(VIBE_SIGNATURE)
|
||||
|
||||
typedef enum VibeAttributeId {
|
||||
VibeAttributeId_Invalid = 0x00,
|
||||
VibeAttributeId_Notes = 0x01,
|
||||
VibeAttributeId_Pattern = 0x02,
|
||||
VibeAttributeId_RepeatDelay = 0x03,
|
||||
} VibeAttributeId;
|
||||
|
||||
typedef struct PACKED VibeScore {
|
||||
uint16_t version;
|
||||
uint8_t reserved[4];
|
||||
uint16_t attr_list_size;
|
||||
GenericAttributeList attr_list;
|
||||
} VibeScore;
|
||||
|
||||
typedef struct PACKED VibeNote {
|
||||
uint16_t vibe_duration_ms;
|
||||
uint8_t brake_duration_ms;
|
||||
int8_t strength;
|
||||
} VibeNote;
|
||||
|
||||
typedef uint8_t VibeNoteIndex;
|
||||
|
||||
// Fetches a vibe score from resources, specifying a ResAppNum
|
||||
// Must be freed using vibe_score_destroy()
|
||||
VibeScore *vibe_score_create_with_resource_system(ResAppNum app_num, uint32_t resource_id);
|
||||
|
||||
// Fetches a vibe score from resources, using the caller ResAppNum
|
||||
// Must be freed using vibe_score_destroy()
|
||||
VibeScore *vibe_score_create_with_resource(uint32_t resource_id);
|
||||
|
||||
// Checks whether a vibe score is valid, given its data size
|
||||
bool vibe_score_validate(VibeScore *score, uint32_t data_size);
|
||||
|
||||
// Returns the duration in ms of the vibe pattern specified by the score
|
||||
unsigned int vibe_score_get_duration_ms(VibeScore *score);
|
||||
|
||||
// Returns the value of the repeat_delay attribute, or 0 if it does not exist
|
||||
unsigned int vibe_score_get_repeat_delay_ms(VibeScore *score);
|
||||
|
||||
// Queues the vibe pattern specified by the score and starts the vibe motor
|
||||
// If there the system is already playing a vibe, this will do nothing
|
||||
void vibe_score_do_vibe(VibeScore *score);
|
||||
|
||||
// Frees a vibe created with vibe_score_create_with_resource
|
||||
void vibe_score_destroy(VibeScore *score);
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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 "vibe_score_info.h"
|
||||
|
||||
#include "resource/resource_ids.auto.h"
|
||||
#include "services/common/i18n/i18n.h"
|
||||
#include "system/passert.h"
|
||||
#include "util/size.h"
|
||||
|
||||
typedef enum AlertType {
|
||||
AlertType_Notifications = 1 << 0,
|
||||
AlertType_Calls = 1 << 1,
|
||||
AlertType_Alarms = 1 << 2,
|
||||
AlertType_AlarmsLPM = 1 << 3,
|
||||
AlertType_All = AlertType_Notifications | AlertType_Calls | AlertType_Alarms,
|
||||
} AlertType;
|
||||
|
||||
typedef struct {
|
||||
const VibeScoreId id;
|
||||
const char *name;
|
||||
const int alert_types;
|
||||
const uint32_t resource_id;
|
||||
} VibeScoreInfo;
|
||||
|
||||
#define VIBE_DEF(identifier, enum_name, name_str, alert_types_arg, res_id)\
|
||||
{ .id = identifier, \
|
||||
.name = name_str, \
|
||||
.alert_types = alert_types_arg, \
|
||||
.resource_id = res_id },
|
||||
|
||||
static const VibeScoreInfo S_VIBE_MAP[] = {
|
||||
#include "vibes.def"
|
||||
};
|
||||
#undef VIBE_DEF
|
||||
|
||||
#define VIBE_MAP_SIZE ARRAY_LENGTH(S_VIBE_MAP)
|
||||
|
||||
static const VibeScoreInfo *prv_vibe_score_find_info(VibeScoreId id) {
|
||||
for (unsigned int x = 0; x < VIBE_MAP_SIZE; x++) {
|
||||
if (S_VIBE_MAP[x].id == id) {
|
||||
return &S_VIBE_MAP[x];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t vibe_score_info_get_resource_id(VibeScoreId id) {
|
||||
const VibeScoreInfo *info = prv_vibe_score_find_info(id);
|
||||
return info ? info->resource_id : RESOURCE_ID_INVALID;
|
||||
}
|
||||
|
||||
const char *vibe_score_info_get_name(VibeScoreId id) {
|
||||
const VibeScoreInfo *info = prv_vibe_score_find_info(id);
|
||||
return info ? info->name : "";
|
||||
}
|
||||
|
||||
static int prv_get_index(VibeScoreId id) {
|
||||
for (unsigned int x = 0; x < VIBE_MAP_SIZE; x++) {
|
||||
if (S_VIBE_MAP[x].id == id) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
VibeScoreId vibe_score_info_cycle_next(VibeClient client, VibeScoreId curr_id) {
|
||||
AlertType alert_type;
|
||||
switch (client) {
|
||||
case VibeClient_Notifications: {
|
||||
alert_type = AlertType_Notifications;
|
||||
break;
|
||||
}
|
||||
case VibeClient_PhoneCalls: {
|
||||
alert_type = AlertType_Calls;
|
||||
break;
|
||||
}
|
||||
case VibeClient_Alarms: {
|
||||
alert_type = AlertType_Alarms;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
WTF;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int currently_showing_index = prv_get_index(curr_id);
|
||||
unsigned int search_index = (currently_showing_index + 1) % VIBE_MAP_SIZE;
|
||||
|
||||
while (search_index != currently_showing_index) {
|
||||
if ((S_VIBE_MAP[search_index].alert_types & alert_type) == alert_type) {
|
||||
return S_VIBE_MAP[search_index].id;
|
||||
}
|
||||
search_index = (search_index + 1) % VIBE_MAP_SIZE;
|
||||
}
|
||||
|
||||
return curr_id;
|
||||
}
|
||||
|
||||
bool vibe_score_info_is_valid(VibeScoreId id) {
|
||||
const VibeScoreInfo *info = prv_vibe_score_find_info(id);
|
||||
return (id != VibeScoreId_Invalid) &&
|
||||
info &&
|
||||
((id == VibeScoreId_Disabled) || (info->resource_id != RESOURCE_ID_INVALID));
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "services/normal/vibes/vibe_client.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define VIBE_DEF(identifier, enum_name, name_str, alert_types_arg, res_id)\
|
||||
VibeScoreId_##enum_name = identifier,
|
||||
typedef enum VibeScoreId {
|
||||
VibeScoreId_Invalid = 0,
|
||||
#include "vibes.def"
|
||||
} VibeScoreId;
|
||||
#undef VIBE_DEF
|
||||
|
||||
#if PLATFORM_SPALDING
|
||||
#define DEFAULT_VIBE_SCORE_NOTIFS (VibeScoreId_Pulse)
|
||||
#define DEFAULT_VIBE_SCORE_INCOMING_CALLS (VibeScoreId_Pulse)
|
||||
#define DEFAULT_VIBE_SCORE_ALARMS (VibeScoreId_Pulse)
|
||||
#else
|
||||
#define DEFAULT_VIBE_SCORE_NOTIFS (VibeScoreId_NudgeNudge)
|
||||
#define DEFAULT_VIBE_SCORE_INCOMING_CALLS (VibeScoreId_Pulse)
|
||||
#define DEFAULT_VIBE_SCORE_ALARMS (VibeScoreId_Reveille)
|
||||
#endif
|
||||
|
||||
// Returns the ResourceId for the VibeScore represented by this id.
|
||||
// If the id does not exist, the ResourceId of the first vibe in S_VIBE_MAP is returned
|
||||
uint32_t vibe_score_info_get_resource_id(VibeScoreId id);
|
||||
|
||||
// Returns the name of the VibeScore represented by this id
|
||||
// If the id does not exist, the name of the first vibe in S_VIBE_MAP is returned
|
||||
const char *vibe_score_info_get_name(VibeScoreId id);
|
||||
|
||||
// Returns the next vibe score playable by the client from the array defined by vibes.def
|
||||
// Wraps around and continues searching if the end of the array is reached
|
||||
// Returns current_id if there is no next vibe score
|
||||
VibeScoreId vibe_score_info_cycle_next(VibeClient client, VibeScoreId curr_id);
|
||||
|
||||
// Checks if the vibe score id exists and if the associated VibeScoreInfo contains a valid
|
||||
// resource_id
|
||||
bool vibe_score_info_is_valid(VibeScoreId id);
|
||||
@@ -0,0 +1,16 @@
|
||||
// IDs must be monotonically increasing, i.e. they must never be reused
|
||||
// ID 0 is reserved for "Invalid". Do not use!
|
||||
|
||||
VIBE_DEF(1, Disabled, i18n_ctx_noop("NotifVibe", "Disabled"), (AlertType_Notifications | AlertType_Calls), RESOURCE_ID_INVALID)
|
||||
VIBE_DEF(2, StandardShortPulseLow, i18n_noop("Standard - Low"), AlertType_Notifications, RESOURCE_ID_VIBE_SCORE_STANDARD_SHORT_LOW)
|
||||
VIBE_DEF(3, StandardLongPulseLow, i18n_noop("Standard - Low"), (AlertType_Calls | AlertType_Alarms), RESOURCE_ID_VIBE_SCORE_STANDARD_LONG_LOW)
|
||||
VIBE_DEF(4, StandardShortPulseHigh, i18n_noop("Standard - High"), AlertType_Notifications, RESOURCE_ID_VIBE_SCORE_STANDARD_SHORT_HIGH)
|
||||
VIBE_DEF(5, StandardLongPulseHigh, i18n_noop("Standard - High"), (AlertType_Calls | AlertType_Alarms), RESOURCE_ID_VIBE_SCORE_STANDARD_LONG_HIGH)
|
||||
VIBE_DEF(8, Pulse, i18n_noop("Pulse"), AlertType_All, RESOURCE_ID_VIBE_SCORE_PULSE)
|
||||
VIBE_DEF(9, NudgeNudge, i18n_noop("Nudge Nudge"), AlertType_All, RESOURCE_ID_VIBE_SCORE_NUDGE_NUDGE)
|
||||
#if !PLATFORM_SPALDING
|
||||
VIBE_DEF(10, Jackhammer, i18n_noop("Jackhammer"), AlertType_All, RESOURCE_ID_VIBE_SCORE_JACKHAMMER)
|
||||
VIBE_DEF(11, Reveille, "Reveille", AlertType_Alarms, RESOURCE_ID_VIBE_SCORE_REVEILLE)
|
||||
VIBE_DEF(12, Mario, "Mario", AlertType_All, RESOURCE_ID_VIBE_SCORE_MARIO)
|
||||
#endif
|
||||
VIBE_DEF(13, AlarmsLPM, "ALARMS LPM", AlertType_AlarmsLPM, RESOURCE_ID_VIBE_SCORE_ALARM_LPM)
|
||||
Reference in New Issue
Block a user