// Exercise the production touch debounce and serialized conversation manager. const fs = require('node:fs'), path = require('node:path'); const root = path.resolve(__dirname, '..'); const touch = fs.readFileSync(path.join(root, 'main/conv_ai_embedded_kit.c'), 'utf8'); const manager = fs.readFileSync(path.join(root, 'components/application/service/conv_service/src/volc_conv_service.c'), 'utf8'); function extract(text, first, next) { const a = text.indexOf(first), b = text.indexOf(next, a); if (a < 0 || b < 0) throw new Error('Missing production section: ' + first); return text.slice(a, b); } process.stdout.write(String.raw` #include #include #include #include typedef uint32_t TickType_t; typedef int aios_ret_t; #define ESP_PLATFORM 1 typedef void *TaskHandle_t; typedef struct {int id;} aios_event_t; typedef struct {void *conv_thread_id;} volc_conv_service_manager_t; typedef struct {void *display_handle;} volc_hal_context_t; typedef void *volc_hal_display_t; typedef struct {char name[32];int stack_size,priority,stack_in_ext;} volc_osal_thread_param_t; enum {VOLC_SERVICE_AI_CONVERSATION_START=100,VOLC_SERVICE_AI_CONVERSATION_INTERRUPT, VOLC_SERVICE_AI_CONVERSATION_QUIT,VOLC_SERVICE_AI_CONVERSATION_OVER,VOLC_SERVICE_AI_CONVERSATION_TOGGLE}; enum {AIOS_Ret_NotHandled,AIOS_Ret_Handled}; #define VOLC_DISPLAY_OBJ_STATUS 0 #define VOLC_DISPLAY_TEXT 0 #define pdMS_TO_TICKS(x) (x) #define ESP_LOGI(...) ((void)0) static volc_hal_context_t hal; static bool create_fail,publish_fail,hal_missing; static bool standby,wake_accept=true; static unsigned wakes; static bool call_client_standby(void){return standby;} static bool device_control_request_screen_wake(void){if(!wake_accept)return false;wakes++;return true;} static unsigned starts,stops,prepares,resets,events,reaps; static int task_data; static void *handle=&task_data; static volc_conv_service_manager_t state; static volc_hal_context_t *volc_get_global_hal_context(void){return hal_missing?NULL:&hal;} static void volc_hal_display_set_content(void *h,int o,int t,const char *c){(void)h;(void)o;(void)t;(void)c;} static void conv_ai_service_prepare_task(void){prepares++;} static void conv_ai_service_task(void *p){(void)p;} static void conv_ai_service_task_stop(void){stops++;} static void conv_ai_service_diagnostic_reset(void){resets++;} static void volc_osal_thread_destroy(void *h){assert(h==&handle);} static void vTaskDeleteWithCaps(TaskHandle_t h){assert(h==&task_data);reaps++;} static int volc_osal_thread_create(void **h,volc_osal_thread_param_t *p,void (*f)(void*),void *arg){ (void)p;(void)f;(void)arg;starts++;if(create_fail)return -1;*h=&handle;return 0; } ` + extract(manager, 'static aios_ret_t __state_conversation(', '\nstatic aios_ret_t __state_init(') + String.raw` static int aios_event_pub(int id,void *a,void *b){ assert(id==VOLC_SERVICE_AI_CONVERSATION_TOGGLE&&!a&&!b);events++; if(publish_fail)return -1; aios_event_t e={id};assert(__state_conversation(&state,&e)==AIOS_Ret_Handled);return 0; } ` + extract(touch, '/* SCREEN_CALL_TAP_BEGIN:', '/* SCREEN_CALL_TAP_END */') + String.raw` int main(void){ screen_call_tap(0);assert(starts==1&&prepares==1&&state.conv_thread_id); screen_call_tap(100);screen_call_tap(299);assert(events==1&&!stops); // A second deliberate tap stops even within the former five-second guard. screen_call_tap(300);assert(stops==1&&starts==1&&state.conv_thread_id); // Connecting/stopping retain admission; rapid repeated taps cannot restart. screen_call_tap(600);screen_call_tap(900);assert(stops==3&&starts==1); aios_event_t over={VOLC_SERVICE_AI_CONVERSATION_OVER}; __state_conversation(&state,&over);assert(!state.conv_thread_id); screen_call_tap(1200);assert(starts==2&&state.conv_thread_id); aios_event_t quit={VOLC_SERVICE_AI_CONVERSATION_QUIT}; __state_conversation(&state,&quit);assert(stops==4&&state.conv_thread_id); __state_conversation(&state,&over); create_fail=true;screen_call_tap(1500);assert(starts==3&&resets==1&&!state.conv_thread_id); create_fail=false;screen_call_tap(1800);assert(starts==4&&state.conv_thread_id); __state_conversation(&state,&over); // Failed event delivery does not consume the debounce window. publish_fail=true;screen_call_tap(2100);assert(starts==4); publish_fail=false;screen_call_tap(2101);assert(starts==5&&state.conv_thread_id); // Unsigned tick rollover preserves the short debounce. screen_call_tap(UINT32_MAX-100);assert(stops==5); screen_call_tap(100);assert(stops==5); screen_call_tap(199);assert(stops==6&&starts==5); assert(reaps==3); // A sleeping screen consumes the tap as wake, never as call toggle. __state_conversation(&state,&over); unsigned old_events=events,old_starts=starts; standby=true;screen_call_tap(500);assert(wakes==1&&events==old_events&&starts==old_starts); standby=false;screen_call_tap(501);assert(events==old_events); screen_call_tap(800);assert(events==old_events+1&&starts==old_starts+1); __state_conversation(&state,&over); standby=true;wake_accept=false;screen_call_tap(1100);assert(wakes==1); wake_accept=true;screen_call_tap(1101);assert(wakes==2&&starts==old_starts+1); puts("PASS screen tap: idle start, second tap hangup at 300ms, connecting/closing admission, repeated stop, OVER reopen, create failure, delivery retry, tick rollover"); return 0; } `);